華南理工大學計算機研究生複試機試複習
調研後發現近三年機試都是資料庫+C#做一個小型管理系統。在這裡邊複習邊做筆記。
拿15的作為練手材料。
首先是建立資料庫
注意將資料庫的檔案跟日誌的路徑放到考試要求的資料夾下。
然後點選右上角的新建查詢來建表。建議有約束的表格用SQL語言來建速度較快。
一、建立資料庫,並建立以下各表 一個員工可以到多個不同公司上班。
員工關係表EMPLOYEE(員工號EmpNo,員工姓名EmpName,性別EmpSex,年齡EmpAge)
示例:E01, 張三,男, 20
工作關係表WORKS(EmpNo員工號,CmpNo公司號,Salary薪水)
示例:E01,C01,2000
公司關係表COMPANY(CmpNo公司號,CmpName公司名)
示例:C01,陽關科技
通過近三年的題目發現。一般都是建立3個表,中間的表有兩個外來鍵是來自於第1, 3兩個表的,所以建表前看清楚,先建兩個獨立的表。
CREATE TABLE EMPLOYEE(
EmpNo varchar(10) primary key,
EmpName nvarchar(20) not null,
EmpSex nvarchar(10) check(EmpSex='男' or EmpSex='女'),
EmpAge int check(EmpAge>0));
注意
- 性別與年齡要加入檢測。能檢測的都檢測
- nvarchar與varchar的區別:中文多點的用nvarchar。
- 建完表後左側欄沒有更新,需要右擊“表”這一項進行重新整理。
第三個表COMPANY
create table COMPANY(
CmpNo varchar(10) primary key,
CmpName nvarchar(20) not null);
第二個表WORKS
CREATE TABLE WORKS(
CmpNo varchar(10),
EmpNo varchar(10),
Salary int check(Salary>0),
PRIMARY KEY(EmpNo, CmpNo),
foreign key (EmpNo) references EMPLOYEE(EmpNo),
foreign key (CmpNo) references COMPANY(CmpNo));
關係的完整性
實體完整性:必須滿足的完整性之一,若一個屬性是主屬性,則不能為空。
參照完整性:必須滿足的完整性之二,比如WORKS中引用了EMPLOYEE的EmpNo,則EmpNo必須是存在於EMPLOYEE中的。
之後便是插入資料,一定要使用語言。可能會要求將insert語句也儲存下來。
右鍵表格,選編輯前200行。
之後備份。右擊我們的資料庫SCUT,任務,備份。記得修改路徑到非C盤。填寫檔名加字尾“bak”.
二、基於上述資料庫,請使用sql server2005+vs2008或vs2010完成員工資訊管理系統,並生成相應的可執行檔案(檔名為你的名字)。
具體要求如下:
- 要求程式與資料庫能進行有效連線,並具有完善的人機互動介面, 要求有引數輸入介面和執行按鈕,在介面上有結果輸出展現區, 要求不要把所有操作全部集中在一個選單內。
2.完成對員工關係表的新增,刪除,修改和瀏覽四項功能。老師的性別要求用單選按鈕實現。(15分)
3.統計和查詢:
(1)根據員工號或員工名查詢員工所在的公司名和工資,員工號或員工名不能文字輸入,要求使用下拉選單實現,並與資料庫中現有資訊一致(10分)
(2)統計年齡至少為40歲員工的總工資,工資按從大到小順序排列;與資料庫中現有資訊一致(10分)
(3)查詢至少具有兩份工作員工的姓名和其公司名。(10分)
4.具有資料完整性校驗功能,當出現數據異常和操作異常時,程式應給出清楚完整的異常提示資訊。(10分)
先解決SQL查詢問題。
首先解決的思路就是將所需要的資訊的表連線在一起。使用外來鍵相連。比如將EMPLOYEE& COMPANY相連,select * from EMPLOYEE,COMPANY where EMPLOYEE.EmpNo=COMPANY.CmpNo;
解:(1)表中需要員工號EmpNo,員工名EmpName,員工所在公司名CmpName和工資Salary。所以需要連線三個表。
select EMPLOYEE.EmpNo as '員工號',EMPLOYEE.EmpName as '員工名',
COMPANY.CmpName as '公司名', Salary as '工資'
where EMPLOYEE.EmpNo=WORKS.EmpNo
and COMPANY.CmpNo=WORKS.CmpNo;
- 選出的列名另名為可以用as.
(2)
查詢條件1:40歲以上員工
查詢條件2:總工資
查詢條件3:從大到小排列
- 查詢條件1:EMPLOYEE.EmpAge>=40
- 查詢條件2:使用GROUP BY聚類查詢。group
by的意思是將表按條件分組,再按組內的來進行數學運算。比如WORKS裡員工可能在多個公司有崗位工資,我們想查詢每個員工的總工資,那麼就GROUP
BY EmpNo,在select中select sum(salary)。需要注意的是select中的表的列需要在group
by中有出現。如果group
by中沒有EMPLOYEE.EmpName,而select中有EMPLOYEE.EmpName,則會顯示group
by中沒有該元素,算術表示式則不需要,如下程式碼的sum(WORKS.Salary) as salary。having則是
用於group - 查詢條件3:order by xxx desc.(升序則是asc)
select EMPLOYEE.EmpNo, EMPLOYEE.EmpName, EMPLOYEE.Empage, sum(WORKS.Salary) as salary
from EMPLOYEE, WORKS
where EMPLOYEE.EmpNo=WORKS.EmpNo
group by EMPLOYEE.EmpNo, EMPLOYEE.EmpName,EMPLOYEE.EmpAge
having EMPLOYEE.EmpAge>40
order by salary desc;
(3)至少有兩份工作的員工及公司名
計算個數使用count。
select EMPLOYEE.EmpNo
from WORKS
group by EMPLOYEE.EmpNo
having count(EMPLOYEE.EmpNo)>=2;
我們需要這個表中的EmpNo來查詢員工的名字,以及公司名。所以連線4個表。這裡涉及到巢狀子查詢。可以直接將上面程式碼作為一個獨立的表格,比如查詢這些有兩份工作的員工名字
select EMPLOYEE.EmpName
from EMPLOYEE
where EMPLOYEE.EmpNo in (
select EMPLOYEE.EmpNo
from WORKS
group by EMPLOYEE.EmpNo
having count(EMPLOYEE.EmpNo)>=2);
所以連線四個表。則是
select EMPLOYEE.EmpName, COMPANY.CmpName
from EMPLOYEE, COMPANY, (
select EMPLOYEE.EmpNo
from WORKS
group by EMPLOYEE.EmpNo
having count(EMPLOYEE.EmpNo)>=2) as c1
where EMPLOYEE.EmpNo=c1.EmpNo
and EMPLOYEE.CmpNo=COMPANY.CmpNo;
之後是C#程式設計。
C#首先是拖控制元件,有點類似於Andriod。在vs中的檢視中開啟工具箱側邊欄。常用的控制元件用圖中紅框框出來了
先審題。題目要求不要把所有操作全部集中在一個選單內。所以我們使用容器裡的TabControl。將其拖到Form1的視窗中右鍵屬性。在如圖中的TabPage位置進入就可以新增,移除標籤,並且修改標籤中的字。根據題目有四個要求。1是一個顯示當前資料庫中的EMPLOYEE表格內容並且提供增刪改功能,2,3,4分別是上面實現的查詢。所以總有4個tab
之後每個標籤下都使用ListView來顯示查詢結果。
C#之ListView
首先是屬性:這裡只需要改幾處,
- FullRowSelect-true
- MultiSelect-false
- GridLines-true
View-details
程式碼:以上屬性更改後點擊一項同一行的都會被選中。
· 在修改時需要在兩個視窗間傳遞資料,參考安卓的Intent,我們需要讀取該行的資料放到Intent中。此時讀取第一行的第一個資料的程式碼是(注意是陣列從0開始)listView1.SelectedItems[0].SubItems[0].Text;
其中SelectedItems是一個數組,裡面存放了你選擇的ListView行。SubItems則是該行中的某一列。
· 在改與刪時程式碼需要加入判斷是否有選中的邏輯。所以此時程式碼是listView1.SelectedItems.Count>0
,否則會報錯:未處理ArgumentOutOfRangeExceptionInvalidArgument=“0”的值對於“index”無效。
引數名: index
· 在顯示查詢到的資料時需要先載入表頭才能夠顯示出來。程式碼是
//n是該行分成n等分,m是這個表頭佔m/n行的寬度
listView1.Columns.Add('表頭名',listView1.Width/n-m',HorizontalAlignment.Left)
· 載入表頭後要將資料一個個新增到行,行組成表。程式碼有通用性
//通過查表返回DataTable型別表格,資料由此表格得到,@表示禁止字串強制轉換。注意資料庫語句最後要加‘;’
DataTable table=db.GetBySql(@"select * from EMPLOYEE;");
//與EndUpdate()配合有效提高載入速度,注意先建表頭
listView1.BeginUpdate();
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);
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] + ""; //第一列使用Text。後面才是SubItem
}
else
{
listViewItem.SubItems.Add(table.Rows[i][j] + "");
}
listView1.Items.Add(listViewItem);//新增該行
}
}
listView1.EndUpdate();
在判斷資料有效性時需要遍歷整個ListView,使用foreach遍歷listView中的ListViewItem。與上面的相同,SubItems[i]表示這一行的第i-1列的內容。
foreach(ListViewItem item in this.listView1.Items){
if(Intent.dict['form2_textbox2_text"]+""==item.SubItems[0].Text){}
}
注意在新增行時,第一列是使用listViewItem.Text來設定的。之後則是使用listViewItem.SubItems.Add來新增。dataTable.Row[i][j]要加“”強制轉換成字串
刪除選中行:listView1.SelectedItems[0].Remove();
C#之ComboBox
combobox是下拉框。即題目要求的要求使用下拉選單實現。屬性只需要將DropDownStyle設定為DropDownList(不可編輯)。
將員工名/員工編號載入進comboBox
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;//設定顯示為第1個
獲取選中的comboBox:comboBox1.Text
在選中查詢後,若想表格只顯示當前的員工資訊,則需要將listView清空,使用listView2.clear();
但使用後表頭也會沒有,所以需要注意每次clear後重新增加表頭
C#之Button
與安卓類似。直接在設計介面選中按鈕,然後在屬性框中的閃電標誌下的Click中填入Click事件函式的函式名,回車,就會自動生成函式
C#之視窗
在Program.cs中可以設定應用程式入口點,預設新建專案時的視窗檔案Form1.cs。
Form的屬性設定FormBorderStyle為FixedSingle,MaximizeBox,MinimizeBox為false,即無法最大最小化。StartPosition為CenterScreen。事件中Load即彈出視窗時執行的函式。這個專案中有多個子選單。幾個查詢都是點選標籤即顯示,所以在彈出視窗時就要查詢好查好,放在Form1_Load()中。滑鼠點選事件則按上面說的自動生成,在load函式外。
新增修改員工時需要彈出第二個視窗來填寫資訊,這時候直接新建一個物件Form2就好。Form2是個新的視窗Form2 form2=new Fomr2();
若要製造登陸視窗切換到另外一個視窗的效果,則使用
this.Hide();
form2.Show();
如果是非初始視窗則可以使用close。
視窗間資訊交換
與安卓一樣使用Intent的概念。新建一個Intent靜態類,這個類是個字典。這樣就可以通過鍵值來儲存資訊,通過靜態的來共享。
using System;
using System.Collections.Generic;
using System.Text;
namespace SCUT
{
class Intent
{
public static Dictionary<string, Object> dict=new Dictiionary<string, object>();
}
}
例子:
//存:
Intent.dict["form2_textbox1_text"]=textBox1.Text;
Intent.dict["form2_raidobutton"]="男";
//取:
listViewItem.SubItems.Add(Intent.dict["form2_textbox1_text"]+"");
db.getBySql(@"select EmpName From EMPLOYEE where EmpNo='"+Intent.dict["form2_textbox2_text"]+"';"
連線資料庫語句時要特別該變數是字串還是數字,如果是varchar則要加’ ‘,數字則不用。
使用DialogResult來判斷是否正確返回
//form1.cs
if(form2.showDialog()==DialogResult.OK){}
//form2.cs
this.DialogResult=DialogReslut.OK;
this.close();
C#之其他控制元件
- RadioButton:多選一用的RadioButton要放在同一個panel裡保證互斥,要取被選中的radioBUtton需要一個個檢測if(radioButton.Checked),獲取值是radioButton.Text;
- Label: 增加文字說明。
SqlServer
在最開始,先建立兩個工具類,一個是資料庫的操作,一個是Intent。這裡說資料庫:
首先是建立連線。寫在建構函式中:
using System;
using System.Collections.Generic;
using System.Text;
using System.Data;//DataTable用到
using System.Data.SqlClient;//一系列的資料庫操作類用到
private SqlConnection sqlConnection;
public DB(){
sqlConnection=new SqlConnection(@"server=.\SQLEXPRESS;database=SCUT;Trusted_Connection=SSPI;");//server名字看資料庫的
sqlConnection.Open();//要Open,否則無法增刪
}
資料庫的操作分為增刪改和查兩大類。因為前一類不會返回表,只執行操作,而查詢需要返回的表。
所以分成兩個函式;
public Datatable getSql(string sql){
SqlDataAdapter sqlDataAdapter=new SqlDataAdapter(new SqlCommand(sql, sqlConnection));
DataTable dataTable=new DataTable();
sqlDataAdapter.Fill(dataTable);
return dataTable;
}
public void setSql(string sql){
new SqlCommand(sql, sqlConnection).ExecuteNonQuery();
}
最後需要解構函式關閉資料庫
public void Dispose(){
sqlConnection.Close();
}
最後效果如圖: