版權聲明:本文爲博主轉載文章,原文網址在下面給出,如果欣賞!覺得好,給原博主回個貼就行!
原文作者:yongh701
原文地址:【C#】華南理工大學計算機考研複試題目
備註:博主是個菜鳥,這是第一篇博客,可能會在排版上面有些錯誤,可以直接去原網址查看。
本人是16級華工計科院統考生,在學校並沒有學過C#,通過閱讀原博主的一系列文章,學習了C#編程的一些基本知識,非常感謝,特轉載爲本人第一篇博客。
1. 當時並沒有找到過多的歷年複試機試題,其實在王道論壇上歷年試題非常詳細,計算機考研尋找資料時到王道論壇上更加方便。王道論壇
2. 學長編寫的代碼中在“員工表增刪改查”時“修改”與“刪除”時,可以加一句判斷listview1是否選中的代碼。
3. 數據表建立時有外鍵約束,修改以及刪除都可能違背外鍵約束,使程序出現異常,可在“修改”和“刪除”功能的數據庫操作代碼上加上try{}catch{}語句(下圖爲修改時的語句)
4. 如果textbox中輸入文字過長,超過數據庫中的數據長度上限也會保存,可以設置textbox的最大長度
下爲正式轉載文章:
華南理工大學計算機考研複試,在34所408聯考高校中比較特別,除去各個學校都存在的面試環節,對比於其它科目傳統筆試,華南理工大學更加傾向於使用C#窗體的程序製作來進行面試複試,這與部分學校使用傳統的C語言編寫算法不同。華南理工大學計算機考研複試的工程量、深度堪比一個小型的軟件項目。
網上一直對此資料甚小,有也是部分同學的回憶版,草草地敘述一下題目,也寫寫簡單編程思想。並沒有一份詳盡的資料。這對於部分沒有接觸過C#窗體的同學,有點痛苦。
下面講解如何利用C#、SQL Server2005、VS2010完成華南理工大學計算機考研複試,以最新的2015年3月份的真題爲例。
首先,第一大題,10分,送分的題目:
1、創建文件夾“d:\研究生複試\[你的中文姓名]\” 例: 張三,應創建“d:\研究生複試\張三”文件夾。 所有文檔和答案都放在這個文件夾中。
2、在文件夾中建立一個readme文件(.txt或.doc均可),以說明所用的軟件工具。
3、設計文檔,文件名爲Info.doc,數據庫連接說明:如用戶名,密碼,ODBC/JDBC等數據源配置等(數據庫連接方式及配置參數)如果必要,可以說明運行方式和相關參數 如果功能不能通過運行,則給出相應的源代碼。
4、在你的目錄中建立SOURCE目錄,系統源文件放在該目錄下
5、考完後請不要關機,人離開就可以了。
答:
在做題之前,自己先檢測機器有沒有Visual Studio 2005/2008/2010、開始菜單,找到Microsoft SQL Server 2005這個文件夾中的SQL Server Management Studio Express,沒有這裏工具,馬上舉手,換機器。畢竟做題時間非常緊,以下的所有內容不難,對於我這樣平時寫程序的人來說,甚至覺得就是無聊,但是如此之多的需求,我用了遠超於1個半小時完成,各位考生好自爲之。
第1題,建立文件夾就不展示了,相信每一個用過計算機的同學都會,第5題自己記得別關機,相信沒有考生會這麼傻吧?
第4題,一會在第三大題搞C#的在一開始創建工程時候注意好路徑的選擇~。
第2、3題的說明文檔留在最後那麼的10-20分鐘寫,做完沒做完都好,對整個工程做一個好好的總結,同時給改卷老師好好說明你做了什麼,這裏暫時不理會,沒寫完程序寫毛線!
直接第二大題,數據庫設計,35分
一、建立數據庫,並建立以下各表 一個員工可以到多個不同公司上班。
員工關係表EMPLOYEE(員工號EmpNo,員工姓名EmpName,性別EmpSex,年齡EmpAge)
工作關係表WORKS(EmpNo員工號,CmpNo公司號,Salary薪水)
公司關係表COMPANY(CmpNo公司號,CmpName公司名)
要求:
1、在數據庫中根據上述表的定義創建上述數據庫,同時需建立相應的約束關係
答:(1)首先,你在開始菜單,找到Microsoft SQL Server 2005這個文件夾中的SQL Server Management Studio Express打開它,直接使用如下圖的Windows 身份驗證登錄。
(2)之後,如下圖,右擊“數據庫”,新建一個數據庫
(3)如下圖,這裏以新建一個SCNT(華南理工大學的英文簡稱)數據庫爲例,雖然平時做工程沒有人會修改數據庫路徑的,直接讓系統管理的,但是,現在是考試,那你就將日誌、數據兩個數據庫文件都改到你在第1大題、第1小題,一上來就建立的文件夾。其餘所有參數不改,也沒時間改,點“確定”。
(4)之後,我們在SCNT這個數據庫中新建查詢。
記得寫完的Sql語句,要塗黑之後再執行。
(5)執行如下的SQL語句,完成這一小題。題目設置得相當陰險。一般情況下,關係表是寫在所有表的結尾,最後建立的。因爲關係表中的所有數據都是來自於其它表,沒有其它表的結構是建立不起來的。而改卷老師,故意將關係表擺在中間。
可以看到如下的SQL語句,必須將關係表的建立,擺在最後,這3張表才能順利建立起來。
- --在數據庫中根據上述表的定義創建上述數據庫,同時需建立相應的約束關係
- create table [EMPLOYEE](
- [EmpNo] varchar(8) not null primary key,
- [EmpName] varchar(50) not null,
- [EmpSex] varchar(2) check([EmpSex]='男' or [EmpSex]='女'),
- [EmpAge] int check([EmpAge]>0)
- )
- create table [COMPANY](
- [CmpNo] varchar(8) not null primary key,
- [CmpName] varchar(50) not null
- )
- create table [WORKS](
- [EmpNo] varchar(8) references [EMPLOYEE]([EmpNo]),
- [CmpNo] varchar(8) references [COMPANY]([CmpNo]),
- [Salary] int check([Salary]>0)
- )
同時注意,題目,需要同時建立約束關係。
因此,Sql語句最後,該有的實體完整性、參照完整性、域完整性不能漏,沒有就丟分。
2、將上面的數據輸入到數據庫中相應的表中
這裏,推薦還是用最傳統的SQL語句完成,也就是複製、粘貼改改數據的事情,比用圖形界面操作要快。
- --將上面的數據輸入到數據庫中相應的表中
- insert into [EMPLOYEE] values('E01','張三','女',32);
- insert into [EMPLOYEE] values('E02','李四','男',28);
- insert into [EMPLOYEE] values('E03','王五','女',42);
- insert into [EMPLOYEE] values('E04','趙六','男',37);
- insert into [EMPLOYEE] values('E05','陳七','男',51);
- insert into [COMPANY] values('C01','陽光科技');
- insert into [COMPANY] values('C02','晨光科技');
- insert into [COMPANY] values('C03','未來科技');
- insert into [WORKS] values('E01','C01',3000);
- insert into [WORKS] values('E01','C02',4000);
- insert into [WORKS] values('E02','C02',5000);
- insert into [WORKS] values('E02','C03',2500);
- insert into [WORKS] values('E03','C01',3500);
- insert into [WORKS] values('E04','C02',3000);
- insert into [WORKS] values('E05','C03',2000);
同樣需要注意的是,關係表的數據最後才插入。
而且,清楚地瞭解該字段的數據類型,不是數字,自覺補上'',是數字,千萬別有''
3、將數據庫備份到你的文件夾下,命名爲backupInfo
備份,也就是幾分鐘的事,如下圖,右擊要備份的數據庫,選擇“任務”->"備份"
刪除原有的默認備份路徑之後,添加自定義的路徑。
選好路徑之後,自己寫好備份文件名,注意帶上後綴名,
弄好點確定,即可。
好,這個大題,至此做完,最好能夠在15分鐘之內做完。
下面進入到核心的C#編程,建議這個SQL Server Management Studio Express別關。因爲按照現在市場上軟件編程MVC的思想,都是在數據庫先組織好查詢數據->推到相應的編程語言,這裏是C#窗體中->再組織好數據,打印出來,一會兒自然還要多次用到SQL Server Management Studio Express。
三、基於上述數據庫,請使用sql server2005+vs2008或vs2010完成員工信息管理系統,並生成相應的可運行文件(文件名爲你的名字)。
具體要求如下:
1. 要求程序與數據庫能進行有效連接,並具有完善的人機交互界面, 要求有參數輸入界面和執行按鈕,在界面上有結果輸出展現區, 要求不要把所有操作全部集中在一個菜單內。
2.完成對員工關係表的添加,刪除,修改和瀏覽四項功能。老師的性別要求用單選按鈕實現。(15分)
3.統計和查詢:
(1)根據員工號或員工名查找員工所在的公司名和工資,員工號或員工名不能文本輸入,要求使用下拉菜單實現,並與數據庫中現有信息一致(10分)
(2)統計年齡至少爲40歲員工的總工資,工資按從大到小順序排列;與數據庫中現有信息一致(10分)
(3)查詢至少具有兩份工作員工的姓名和其公司名。(10分)
4. 具有數據完整性校驗功能,當出現數據異常和操作異常時,程序應給出清楚完整的異常提示信息。(10分)
答:
由於題目要求,上來新建C#工程就尤爲注意:
打開VS2010之後,點擊文件->新建->項目,出現如下對話框,在左方的語言欄,請先找到C#編程語言,有可能藏在“其它語言”中,之後選擇C#旗下的Windows。
在選擇“Windows窗體應用程序”的時候,注意,是否有.NET版本的選擇,如果有,這個.NET選擇2.0。不選,如果有.net4.x也可以,編程寫法也一樣的,程序運行起來卡而已。
最後,最最最關鍵的是,就算你代碼不會寫,也要做好的是,選擇好,工程的位置就是你第一題目建立的文件夾下的Source,名稱,按照題目要求,就是你的真實名稱。
之後解決方案的名稱,在你填完 名稱 就自動完成填寫,點擊“確定”之後,就可以正式開始編程。
1、在正式的窗體開發之前,我們先如下圖,在解決方案中,新建兩個類.cs,磨刀不誤砍柴工,
一個是用戶數據庫連接、查詢的DB.cs,這個類的具體作用在《【C#】利用C#窗體與SQL Server的連接、Treeview製作SQL Server數據庫查看器》(點擊打開鏈接)我已經寫過了,這裏不再複製、粘貼一次了,有興趣可以去看看,具體代碼如下:
- using System;
- using System.Collections.Generic;
- using System.Text;
- using System.Data;//DataTable用到
- using System.Data.SqlClient;//一系列的數據庫操作類用到
- namespace SCUT
- {
- class DB : IDisposable
- {
- private SqlConnection sqlConnection;
- public DB()//私有無參構造函數
- {
- sqlConnection = new SqlConnection(@"server=.\SQLEXPRESS;database=SCNT;Trusted_Connection=SSPI;");
- sqlConnection.Open();
- }
- public DataTable getBySql(string sql)
- {//查詢
- SqlDataAdapter sqlDataAdapter = new SqlDataAdapter(new SqlCommand(sql, sqlConnection));
- DataTable dataTable = new DataTable();
- sqlDataAdapter.Fill(dataTable);
- return dataTable;
- }
- public void setBySql(string sql)
- { //修改
- new SqlCommand(sql, sqlConnection).ExecuteNonQuery();
- }
- public void Dispose()
- {//相當於析構函數
- sqlConnection.Close();
- //在C#中關閉數據庫連接不能在類的析構函數中關,否則會拋“內部 .Net Framework 數據提供程序錯誤 1”的異常
- //通過實現C#中IDisposable接口中的Dispose()方法主要用途是釋放非託管資源。
- }
- }
- }
這個類,直接使用《【C#】使用Windows身份驗證連接Sql Server,ListView隨窗體大小的變化而調節列寬》(點擊打開鏈接)中介紹的不安全,但開發快速的Windows身份驗證,去連接數據庫,爲了是不用像《【SQL Server】用戶的設置與授權、sa用戶登錄、查詢一個數據庫中有多少張表》(點擊打開鏈接),再去SQL Server中開用戶。
同時,去掉了這個類單例化的部分,單例主要作用是保證數據庫連接只有一個,不會出現多次連接導致數據庫的擁堵,這裏題目沒要求,不這樣寫,省些代碼,感興趣的,可以到《【php】利用單例模式設計數據庫連接Model類》(點擊打開鏈接)瞭解。
最後,還去掉set、getBySql中對於Sql注入過濾的部分,這些題目都沒要求,不做,省時間,反正就算在實際開發怎麼不及格,考試高分就行。
自己知道這是爲了考試快速答題,但不符合實際開發就可以了。沒必要糾結。
之後,我們再搞一個便於窗體之間與窗體之間傳遞數據的Intent.cs,具體代碼如下,這在《【C#】窗體間互相傳值》(點擊打開鏈接)說過了,這裏不再贅述。就一個存數據的字典容器。
- using System;
- using System.Collections.Generic;
- using System.Text;
- namespace SCUT
- {
- class Intent
- {
- public static Dictionary<string, Object> dict = new Dictionary<string, Object>();
- }
- }
上述兩個工具性的cs類做完之後,可以正式開始窗體的編寫。Form1.cs的佈局、要修改的屬性、添加的事件如下:
對於C#控件毫無概念的同學,可以參考《【C#】簡單窗體程序,判斷是否閏年,禁止窗體調整大小,關閉窗體前的判斷 》(點擊打開鏈接)
這裏擺了一個TabControl,具體可以看《【C#】標籤頁》(點擊打開鏈接),完成題目1,不要將所有功能擺在一個窗體的要求。
因爲接下來要完成4個功能,如下圖,右擊這個TabControl,爲其添加到4個選項卡
在TabControl中的第一個選項卡擺了一個listview,修改的屬性如下圖所示,listview的具體使用,請看《【C#】ListView的使用,對Access數據庫的增刪改查》(點擊打開鏈接)
之後,第2個標籤頁的佈局如下:
這裏應題目的要求,要使用下拉菜單combobox,這個組件在《【C#】文件選擇對話框OpenFileDialog與下列列表ComboBox》(點擊打開鏈接)說過了,這裏不再贅述,注意,將其的DropDownStyle,改成不能編輯的DropDownList。
之後,第三個、第四個標籤頁的佈局內容如下,這兩頁的佈局、所修改的屬性內容基本相同,都是一個label加listview,因爲,題目只是要求將查詢結果打印到窗體上來。
不過,精華在最後的SQL查詢代碼~
接下來,爲了完成第2題對員工表的增刪改查。我們要新建一個窗體Form2,基本的流程同《【C#】窗體間互相傳值》(點擊打開鏈接),其佈局、要修改的屬性、添加的事件如下圖所示:
這裏唯一注意的是,由於題目要求老師的性別要求用單選按鈕實現。那麼你只好在姓名那裏,先拖一個panel1,再放上兩個radiobutton,這樣,兩個radiobutton就自動互斥了。
接下來,雙擊form1.cs、form2.cs各個標籤頁的各個button,爲各個按鈕添加點擊事件。
如果你的vs沒有自動跳轉,請按如下圖的方式,進入代碼編寫界面。
Form1.cs的代碼如下:
- using System;
- using System.Collections.Generic;
- using System.ComponentModel;
- using System.Data;
- using System.Drawing;
- using System.Text;
- using System.Windows.Forms;
- using System.Text.RegularExpressions;//用到了正則表達式
- namespace SCUT
- {
- public partial class Form1 : Form
- {
- DB db;
- public Form1()
- {
- InitializeComponent();
- db = new DB();
- }
- private void Form1_Load(object sender, EventArgs e)
- {
- //員工表 增刪改查 中“查部分”
- //生成表頭
- listView1.Columns.Add("員工號", listView1.Width / 4 - 1, HorizontalAlignment.Left);
- listView1.Columns.Add("員工姓名", listView1.Width / 4 - 1, HorizontalAlignment.Left);
- listView1.Columns.Add("性別", listView1.Width / 4 - 1, HorizontalAlignment.Left);
- listView1.Columns.Add("年齡", listView1.Width / 4 - 1, HorizontalAlignment.Left);
- //表的內容
- DataTable table = db.getBySql(@"select * from [EMPLOYEE]");
- listView1.BeginUpdate();//數據更新,UI暫時掛起,直到EndUpdate繪製控件,可以有效避免閃爍並大大提高加載速度
- for (int i = 0; i < table.Rows.Count; i++)
- {
- ListViewItem listViewItem = new ListViewItem();//生成每一列
- for (int j = 0; j < table.Columns.Count; j++)
- {
- if (j <= 0)
- {
- listViewItem.Text = table.Rows[i][j] + "";
- }
- else
- {
- listViewItem.SubItems.Add(table.Rows[i][j] + "");
- }
- }
- listView1.Items.Add(listViewItem);
- }
- listView1.EndUpdate();//結束數據處理,UI界面一次性繪製
- //查詢3-1
- //加載現有的員工號
- table = db.getBySql(@"select [EmpNo] from [EMPLOYEE]");
- for (int i = 0; i < table.Rows.Count; i++)
- {
- for (int j = 0; j < table.Columns.Count; j++)
- {
- comboBox1.Items.Add(table.Rows[i][j] + "");
- }
- }
- comboBox1.SelectedIndex = 0;
- //加載現有的員工名
- table = db.getBySql(@"select [EmpName] from [EMPLOYEE]");
- for (int i = 0; i < table.Rows.Count; i++)
- {
- for (int j = 0; j < table.Columns.Count; j++)
- {
- comboBox2.Items.Add(table.Rows[i][j] + "");
- }
- }
- comboBox2.SelectedIndex = 0;
- //表3-2
- //統計年齡至少爲40歲員工的總工資,工資按從大到小順序排列
- //生成表頭
- listView3.Columns.Add("員工號", listView1.Width / 5 - 1, HorizontalAlignment.Left);
- listView3.Columns.Add("員工姓名", listView1.Width / 5 - 1, HorizontalAlignment.Left);
- listView3.Columns.Add("性別", listView1.Width / 5 - 1, HorizontalAlignment.Left);
- listView3.Columns.Add("年齡", listView1.Width / 5 - 1, HorizontalAlignment.Left);
- listView3.Columns.Add("總工資", listView1.Width / 5 - 1, HorizontalAlignment.Left);
- //表的內容
- table = db.getBySql(@"select [EMPLOYEE].[EmpNo],[EMPLOYEE].[EmpName],[EMPLOYEE].[EmpSex],[EMPLOYEE].[EmpAge],sum([WORKS].[Salary]) as '總工資' " +
- " from [EMPLOYEE],[WORKS]" +
- " where [EMPLOYEE].[EmpAge]>=40" +
- " and [EMPLOYEE].[EmpNo]=[WORKS].[EmpNo]" +
- " group by [EMPLOYEE].[EmpNo],[EMPLOYEE].[EmpName],[EMPLOYEE].[EmpSex],[EMPLOYEE].[EmpAge]" +
- " order by '總工資' desc");
- listView3.BeginUpdate();//數據更新,UI暫時掛起,直到EndUpdate繪製控件,可以有效避免閃爍並大大提高加載速度
- for (int i = 0; i < table.Rows.Count; i++)
- {
- ListViewItem listViewItem = new ListViewItem();//生成每一列
- for (int j = 0; j < table.Columns.Count; j++)
- {
- if (j <= 0)
- {
- listViewItem.Text = table.Rows[i][j] + "";
- }
- else
- {
- listViewItem.SubItems.Add(table.Rows[i][j] + "");
- }
- }
- listView3.Items.Add(listViewItem);
- }
- listView3.EndUpdate();//結束數據處理,UI界面一次性繪製。
- //表3-3
- //查詢至少具有兩份工作員工的姓名和其公司名
- //生成表頭
- listView4.Columns.Add("員工姓名", listView1.Width / 2 - 2, HorizontalAlignment.Left);
- listView4.Columns.Add("公司名", listView1.Width / 2 - 2, HorizontalAlignment.Left);
- //表的內容
- table = db.getBySql(@"select [EMPLOYEE].[EmpName],[COMPANY].[CmpName] from [EMPLOYEE],[COMPANY],[WORKS],(" +
- " select [EmpName],count([CmpName]) as 'CmpNum'" +
- " from [EMPLOYEE],[WORKS],[COMPANY]" +
- " where [EMPLOYEE].[EmpNo]=[WORKS].[EmpNo]" +
- " and [COMPANY].[CmpNo]=[WORKS].[CmpNo]" +
- " group by [EmpName]" +
- " having count([CmpName])>1" +
- " ) as t1" +
- " where [EMPLOYEE].[EmpNo]=[WORKS].[EmpNo]" +
- " and [COMPANY].[CmpNo]=[WORKS].[CmpNo]" +
- " and [EMPLOYEE].[EmpName]=t1.[EmpName]");
- listView4.BeginUpdate();//數據更新,UI暫時掛起,直到EndUpdate繪製控件,可以有效避免閃爍並大大提高加載速度
- for (int i = 0; i < table.Rows.Count; i++)
- {
- ListViewItem listViewItem = new ListViewItem();//生成每一列
- for (int j = 0; j < table.Columns.Count; j++)
- {
- if (j <= 0)
- {
- listViewItem.Text = table.Rows[i][j] + "";
- }
- else
- {
- listViewItem.SubItems.Add(table.Rows[i][j] + "");
- }
- }
- listView4.Items.Add(listViewItem);
- }
- listView4.EndUpdate();//結束數據處理,UI界面一次性繪製。
- }
- private void button1_Click(object sender, EventArgs e)
- {
- Form2 form2 = new Form2();//聲明要使用form2窗體
- //將form1當前的位置壓入Intent中的dict
- Intent.dict["form1_text"] = this.Text;
- Intent.dict["form1_flag"] = 0;//傳個flag進去代表這是“添加”
- if (form2.ShowDialog() == DialogResult.OK)
- {//這個判斷,將會等到form2被關閉之後才執行,如果form2返回一個OK值
- bool canAdd = true;
- foreach (ListViewItem item in this.listView1.Items)
- {
- if (Intent.dict["form2_textbox1_text"] + "" == item.SubItems[0].Text)
- {
- canAdd = false;
- MessageBox.Show("已存在該員工號!", this.Text);
- break;
- }
- }
- Regex regex = new Regex("^[0-9]*$");
- if (!regex.IsMatch(Intent.dict["form2_textbox3_text"] + ""))//利用正則表達式判斷是否輸入的是數字
- {
- canAdd = false;
- MessageBox.Show("年齡不爲正數!", this.Text);
- }
- if (canAdd)
- {
- ListViewItem listViewItem = new ListViewItem();//在listview中添加一項
- listViewItem.Text = Intent.dict["form2_textbox1_text"] + "";
- listViewItem.SubItems.Add(Intent.dict["form2_textbox2_text"] + "");
- listViewItem.SubItems.Add(Intent.dict["form2_radioButton"] + "");
- listViewItem.SubItems.Add(Intent.dict["form2_textbox3_text"] + "");
- listView1.Items.Add(listViewItem);
- db.setBySql("insert into [EMPLOYEE] values('" + Intent.dict["form2_textbox1_text"] + "','" + Intent.dict["form2_textbox2_text"] + "','" + Intent.dict["form2_radioButton"] + "'," + Intent.dict["form2_textbox3_text"] + ")");
- }
- }
- }
- private void button2_Click(object sender, EventArgs e)
- {
- Form2 form2 = new Form2();//聲明要使用form2窗體
- //將form1當前的位置壓入Intent中的dict
- Intent.dict["form1_text"] = this.Text;
- Intent.dict["form1_flag"] = 1;//傳個flag進去代表這是“修改”
- Intent.dict["form1_selectedItems0"] = listView1.SelectedItems[0].SubItems[0].Text;
- Intent.dict["form1_selectedItems1"] = listView1.SelectedItems[0].SubItems[1].Text;
- Intent.dict["form1_selectedItems2"] = listView1.SelectedItems[0].SubItems[2].Text;
- Intent.dict["form1_selectedItems3"] = listView1.SelectedItems[0].SubItems[3].Text;
- Intent.dict["form1_flag"] = 1;//傳個flag進去代表這是“修改”
- if (form2.ShowDialog() == DialogResult.OK)
- {//這個判斷,將會等到form2被關閉之後才執行,如果form2返回一個OK值
- bool canUpdate = true;
- if (!((Intent.dict["form1_selectedItems0"] + "") == (Intent.dict["form2_textbox1_text"] + "")))//僅當用戶修改過員工號才進行遍歷
- {
- foreach (ListViewItem item in this.listView1.Items)
- {
- if (Intent.dict["form2_textbox1_text"] + "" == item.SubItems[0].Text)
- {
- canUpdate = false;
- MessageBox.Show("已存在該員工號!", this.Text);
- break;
- }
- }
- }
- Regex regex = new Regex("^[0-9]*$");
- if (!regex.IsMatch(Intent.dict["form2_textbox3_text"] + ""))//利用正則表達式判斷是否輸入的是數字
- {
- canUpdate = false;
- MessageBox.Show("年齡不爲正數!", this.Text);
- }
- if (canUpdate)
- {
- ListViewItem listViewItem = new ListViewItem();//在listview中添加一項
- listView1.SelectedItems[0].SubItems[0].Text = Intent.dict["form2_textbox1_text"] + "";
- listView1.SelectedItems[0].SubItems[1].Text = Intent.dict["form2_textbox2_text"] + "";
- listView1.SelectedItems[0].SubItems[2].Text = Intent.dict["form2_radioButton"] + "";
- listView1.SelectedItems[0].SubItems[3].Text = Intent.dict["form2_textbox3_text"] + "";
- db.setBySql("update [EMPLOYEE] set [EmpNo]='" + Intent.dict["form2_textbox1_text"] + "' where [EmpNo]='" + Intent.dict["form1_selectedItems0"] + "';");
- db.setBySql("update [EMPLOYEE] set [EmpName]='" + Intent.dict["form2_textbox2_text"] + "' where [EmpName]='" + Intent.dict["form1_selectedItems1"] + "';");
- db.setBySql("update [EMPLOYEE] set [EmpSex]='" + Intent.dict["form2_radioButton"] + "' where [EmpSex]='" + Intent.dict["form1_selectedItems2"] + "';");
- db.setBySql("update [EMPLOYEE] set [EmpAge]='" + Intent.dict["form2_textbox3_text"] + "' where [EmpAge]='" + Intent.dict["form1_selectedItems3"] + "';");
- }
- }
- }
- private void button3_Click(object sender, EventArgs e)
- {
- db.setBySql("delete from [EMPLOYEE] where [EmpNo]='" + listView1.SelectedItems[0].SubItems[0].Text + "';");
- listView1.SelectedItems[0].Remove();//刪除一定要放在數據庫操作之後,不然選中項再也取不到了
- }
- private void button4_Click(object sender, EventArgs e)
- {
- listView2.Clear();
- //生成表頭
- listView2.Columns.Add("員工號", listView1.Width / 4 - 1, HorizontalAlignment.Left);
- listView2.Columns.Add("員工名", listView1.Width / 4 - 1, HorizontalAlignment.Left);
- listView2.Columns.Add("公司名", listView1.Width / 4 - 1, HorizontalAlignment.Left);
- listView2.Columns.Add("薪水", listView1.Width / 4 - 1, HorizontalAlignment.Left);
- //表的內容
- DataTable table = db.getBySql(@"select [EMPLOYEE].[EmpNo],[EMPLOYEE].[EmpName],[COMPANY].[CmpName],[WORKS].[Salary] from [EMPLOYEE],[COMPANY],[WORKS]" +
- " where [EMPLOYEE].[EmpNo]=[WORKS].[EmpNo]" +
- " and [COMPANY].[CmpNo]=[WORKS].[CmpNo]" +
- " and [EMPLOYEE].[EmpNo]='" + comboBox1.Text + "'");
- listView2.BeginUpdate();//數據更新,UI暫時掛起,直到EndUpdate繪製控件,可以有效避免閃爍並大大提高加載速度
- for (int i = 0; i < table.Rows.Count; i++)
- {
- ListViewItem listViewItem = new ListViewItem();//生成每一列
- for (int j = 0; j < table.Columns.Count; j++)
- {
- if (j <= 0)
- {
- listViewItem.Text = table.Rows[i][j] + "";
- }
- else
- {
- listViewItem.SubItems.Add(table.Rows[i][j] + "");
- }
- }
- listView2.Items.Add(listViewItem);
- }
- listView2.EndUpdate();//結束數據處理,UI界面一次性繪製
- }
- private void button5_Click(object sender, EventArgs e)
- {
- listView2.Clear();
- //生成表頭
- listView2.Columns.Add("員工號", listView1.Width / 4 - 1, HorizontalAlignment.Left);
- listView2.Columns.Add("員工名", listView1.Width / 4 - 1, HorizontalAlignment.Left);
- listView2.Columns.Add("公司名", listView1.Width / 4 - 1, HorizontalAlignment.Left);
- listView2.Columns.Add("薪水", listView1.Width / 4 - 1, HorizontalAlignment.Left);
- //表的內容
- DataTable table = db.getBySql(@"select [EMPLOYEE].[EmpNo],[EMPLOYEE].[EmpName],[COMPANY].[CmpName],[WORKS].[Salary] from [EMPLOYEE],[COMPANY],[WORKS]" +
- " where [EMPLOYEE].[EmpNo]=[WORKS].[EmpNo]" +
- " and [COMPANY].[CmpNo]=[WORKS].[CmpNo]" +
- " and [EMPLOYEE].[EmpName]='" + comboBox2.Text + "'");
- listView2.BeginUpdate();//數據更新,UI暫時掛起,直到EndUpdate繪製控件,可以有效避免閃爍並大大提高加載速度
- for (int i = 0; i < table.Rows.Count; i++)
- {
- ListViewItem listViewItem = new ListViewItem();//生成每一列
- for (int j = 0; j < table.Columns.Count; j++)
- {
- if (j <= 0)
- {
- listViewItem.Text = table.Rows[i][j] + "";
- }
- else
- {
- listViewItem.SubItems.Add(table.Rows[i][j] + "");
- }
- }
- listView2.Items.Add(listViewItem);
- }
- listView2.EndUpdate();//結束數據處理,UI界面一次性繪製
- }
- }
- }
Form2.cs的代碼如下:
- using System;
- using System.Collections.Generic;
- using System.ComponentModel;
- using System.Data;
- using System.Drawing;
- using System.Text;
- using System.Windows.Forms;
- namespace SCUT
- {
- public partial class Form2 : Form
- {
- public Form2()
- {
- InitializeComponent();
- }
- private void Form2_Load(object sender, EventArgs e)
- {
- if ((int)Intent.dict["form1_flag"] == 0)
- {
- this.Text = Intent.dict["form1_text"] + "";
- textBox1.Focus();//設置焦點停留在textBox1中
- }
- else
- {
- this.Text = Intent.dict["form1_text"] + "";
- textBox1.Text = Intent.dict["form1_selectedItems0"] + "";
- textBox2.Text = Intent.dict["form1_selectedItems1"] + "";
- if (Intent.dict["form1_selectedItems2"] + "" == "男")
- {
- radioButton1.Checked = true;
- }
- else {
- radioButton2.Checked = true;
- }
- textBox3.Text = Intent.dict["form1_selectedItems3"] + "";
- textBox1.Focus();//設置焦點停留在textBox1中
- textBox1.SelectAll();//要先有焦點才能全選
- }
- }
- private void button1_Click(object sender, EventArgs e)
- {
- if (textBox1.Text == "" || textBox2.Text == "" || textBox3.Text == "" || (!radioButton1.Checked && !radioButton2.Checked))
- {
- MessageBox.Show("任意一項沒有完成填寫!", this.Text);
- }
- else
- {
- //關閉form2之間,將要傳給form1的值壓入Intent中的dict
- Intent.dict["form2_textbox1_text"] = textBox1.Text;
- Intent.dict["form2_textbox2_text"] = textBox2.Text;
- if (radioButton1.Checked)
- {
- Intent.dict["form2_radioButton"] = "男";
- }
- else
- {
- Intent.dict["form2_radioButton"] = "女";
- }
- Intent.dict["form2_textbox3_text"] = textBox3.Text;
- this.DialogResult = DialogResult.OK;//同時設置返回值爲OK,不設置的話,默認返回Cancel
- this.Close();
- }
- }
- private void button2_Click(object sender, EventArgs e)
- {
- this.Close();
- }
- }
- }
在上述的代碼中:
(1)對於第2題的增刪改查,就是《【C#】ListView的使用,對Access數據庫的增刪改查》(點擊打開鏈接)中的內容,第4大題,要保證輸入的完整性校驗,使用的C#的正則表達式,具體請看《【C#】利用正則表達式判斷輸入是否爲純數字、容器類》(點擊打開鏈接)。
這屬於C#對Sql Server操作的基礎,是每一個學習C#窗體,投身C#開發程序猿的必修課。
做好之後,程序運行結果如下:
(2)對於題目第3-1中,在程序一開始的Load事件,先直接將數據庫員工表EMPLOYEE表中的員工號EmpNo,員工名EmpName查詢出來,加載到兩個Combobox中,用戶點擊button4或者button5,利用Combobox的Text屬性獲得當前Combobox選定的值。
此時,問題演變成,已知員工號、員工名查找員工所在的公司名和工資。
利用多表連接查詢,其實說白了,因爲屬性分佈於EMPLOYEE、WORKS、COMPANY三張表,就是一次性,查詢EMPLOYEE、WORKS、COMPANY三張表,根據建表時的參照完整性,也就是外鍵,添加一個連接條件。
以下是語句:
- select * from EMPLOYEE,COMPANY,WORKS
- where EMPLOYEE.EmpNo=WORKS.EmpNo
- and COMPANY.CmpNo=WORKS.CmpNo
的查詢結果,注意上述語句,寫在C#代碼中,涉及換行,每行的第一個字符,一定是空格,要麼每行的最後一個字符是空格。
同時,表名、字段名加上[],以免觸發系統關鍵字產生歧義。在字符串上補上@,讓此字符串所有要涉及轉義的字符,自動轉義。
在上述查詢結果中,只要取出相應的列,再補上已知的員工號或員工名,構造到C#中就好,將上述的sql語句中的*換成 某某表.某某字段,某某表.某某字段…… 的形式就好,
因此C#中的語句也就演變成:
- DataTable table = db.getBySql(@"select [EMPLOYEE].[EmpNo],[EMPLOYEE].[EmpName],[COMPANY].[CmpName],[WORKS].[Salary] from [EMPLOYEE],[COMPANY],[WORKS]" +
- " where [EMPLOYEE].[EmpNo]=[WORKS].[EmpNo]" +
- " and [COMPANY].[CmpNo]=[WORKS].[CmpNo]" +
- " and [EMPLOYEE].[EmpName]='" + comboBox2.Text + "'");
以上是根據員工名查詢的,根據員工號查詢的同理。
完成之後的截圖如下:
(3)題目3-2中的查詢,沒有任何關於C#的事,核心在於SQL語句的構造,這裏涉及到《【Mysql】利用group by附帶having進行聚類查詢》(點擊打開鏈接)中提到過的聚類查詢。
思考過程如下,同樣還是從:
- select * from EMPLOYEE,COMPANY,WORKS
- where EMPLOYEE.EmpNo=WORKS.EmpNo
- and COMPANY.CmpNo=WORKS.CmpNo
接下來,我們要將查詢結果中,出現 相同的 員工號、員工姓名、性別、年齡 的行,合起來,
整合過程中,對於不相同的公司號、公司名,我們捨棄,而工資,我們採取相加的形式合起來,因此,也就得到如下的查詢語句:
- select EMPLOYEE.EmpNo as '員工號',EMPLOYEE.EmpName as '員工姓名',EMPLOYEE.EmpSex as '性別',EMPLOYEE.EmpAge as '年齡',sum(WORKS.Salary) as '總工資'
- from EMPLOYEE,WORKS
- where EMPLOYEE.EmpAge>=40
- and EMPLOYEE.EmpNo=WORKS.EmpNo
- group by EMPLOYEE.EmpNo,EMPLOYEE.EmpName,EMPLOYEE.EmpSex,EMPLOYEE.EmpAge
查詢結果如下:
最後,在Form1的Load方法中,將這個查詢結果的語句,後面補個order by '總工資' desc,按題目要求工資按從大到小順序排列,再構造到C#窗體的listview3中就好,完成的結果如下:
這題,相對來說,沒有這麼多代碼量,耗時比較少,就是思想過程有點複雜,不過理解了之後就是送分的。
建議先做,分也不少,也簡單。
(4)最後一題,也是差不多性質,只是構造出來的SQL語句更加複雜。
它要查詢至少具有兩份工作員工的姓名和其公司名,我們還是不管,先跟上題一樣,我們先將索要需求的字段,查詢出來的說,之後,同樣聚類,只是這次聚類的方式不同,我們僅需要將查詢結果中,出現 相同的 員工姓名 的行,合起來,合的過程中,行與行之間的 公司名 字段是不同,這個字段通過,計算出現次數合併,其餘字段不要。
因此,Sql語句演變成如下:
- select EmpName,count(CmpName) as 'CmpNum'
- from EMPLOYEE,WORKS,COMPANY
- where EMPLOYEE.EmpNo=WORKS.EmpNo
- and COMPANY.CmpNo=WORKS.CmpNo
- group by EmpName
- having count(CmpName)>1
運行結果如下:
這顯然還不是最後的查詢結果,但離查詢結果已經很接近了。
只要設這個查詢結果爲表t1,再與固有EMPLOYEE、WORKS、COMPANY三張表連接起來查詢即可,連接條件補上t1的EmpName等於EMPLOYEE的EmpName完事,
因此,最終的Sql語句演變成這個樣子:
- select EMPLOYEE.EmpName,COMPANY.CmpName from EMPLOYEE,COMPANY,WORKS,(
- select EmpName,count(CmpName) as 'CmpNum'
- from EMPLOYEE,WORKS,COMPANY
- where EMPLOYEE.EmpNo=WORKS.EmpNo
- and COMPANY.CmpNo=WORKS.CmpNo
- group by EmpName
- having count(CmpName)>1
- ) as t1
- where EMPLOYEE.EmpNo=WORKS.EmpNo
- and COMPANY.CmpNo=WORKS.CmpNo
- and EMPLOYEE.EmpName=t1.EmpName
就是一個4表連接查詢而已,不過其中一個表,是我們的查詢結果,最終構造的C#的listview4,結果如下:
至此整個程序做完。
不過題目還沒有完成,我們要回過頭來完成第一題的文檔。
首先,打開你C#解決方案所在的文件夾:
1、在這個文件夾中,直接打開.sln就能夠重新進入源代碼的編輯界面,因此你在文檔中,寫好打開這個文件,進入解決方案,再點擊左側的各個.cs文件,能夠讀到你的源代碼。
2、關於直接運行的exe,在SCUT(這裏應該會變成你的名字)\SCUT(這裏應該會變成你的名字)\bin\Debug下的.exe,這一點也是需要在文檔中,給改卷老師提到的。
這個文件夾只要你寫程序,編譯過就會自動生成。根本不用浪費時間去生成什麼exe。
其實一般情況做窗體,將Debug文件夾,重命名拖給用戶,讓用戶按裝好.NET Framework 2.0,就OK
3、最後,數據庫,先說明你的數據庫、備份,在什麼什麼文件夾:
然後寫,數據庫,直接負載於Sql Server中,不設密碼,開放權限,直接通過Windows身份登錄就能夠查看。
如不能發現,請根據如下圖的過程,將上圖的mdf,附加到Sql Server中,即可。
反正整個流程就是這樣,當然試題、數據是每年不同的,關鍵是理解其中的方法。
在考試過程不能上網、就只有1.5小時,自己好好背背關鍵代碼,好自爲之。
我整個程序做下來,用的時間遠多於1.5小時,因爲這個軟件規模實在是太大了。
當然整個過程的核心是不變了,SQL查好->C#讀->C#構造數據到前臺,萬變不離其宗。
最後,祝各位通過考研初試,有機會到華南理工複試的計算機考生,在考研複試的過程中,沒有任何意外,穩穩當當,別說做完,能夠在1.5小時中,完成上述80%的內容,基本穩了。