华南理工大学计算机研究生复试机试复习

调研后发现近三年机试都是数据库+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));

注意

  1. 性别与年龄要加入检测。能检测的都检测
  2. nvarchar与varchar的区别:中文多点的用nvarchar。
  3. 建完表后左侧栏没有更新,需要右击“表”这一项进行刷新。

第三个表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完成员工信息管理系统,并生成相应的可运行文件(文件名为你的名字)。

具体要求如下:

  1. 要求程序与数据库能进行有效连接,并具有完善的人机交互界面, 要求有参数输入界面和执行按钮,在界面上有结果输出展现区, 要求不要把所有操作全部集中在一个菜单内

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;
  1. 选出的列名另名为可以用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,否则会报错:未处理ArgumentOutOfRangeException

    InvalidArgument=“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#之其他控件

  1. RadioButton:多选一用的RadioButton要放在同一个panel里保证互斥,要取被选中的radioBUtton需要一个个检测if(radioButton.Checked),获取值是radioButton.Text;
  2. 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();
}

最后效果如图:
这里写图片描述
这里写图片描述
这里写图片描述

这里写图片描述
这里写图片描述

猜你喜欢

转载自blog.csdn.net/BenjaminYoung29/article/details/79442770