一、建表:在数据库中建表、插入数据
1、建表:
员工关系表EMPLOYEE(员工号EmpNo,员工姓名EmpName,性别EmpSex,年龄EmpAge)
工作关系表WORKS(EmpNo员工号,CmpNo公司号,Salary薪水)
公司关系表COMPANY(CmpNo公司号,CmpName公司名)
步骤1 Windows 身份验证登录
2右击“数据库”,新建一个数据库
3如下图,这里以新建一个SCNT(华南理工大学的英文简称)数据库为例,虽然平时做工程没有人会修改数据库路径的,直接让系统管理的,但是,现在是考试,那你就将日志、数据两个数据库文件都改到你在第1大题、第1小题,一上来就建立的文件夹。其余所有参数不改,也没时间改,点“确定”。
4之后,我们在SCNT这个数据库中新建查询。
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语句最后,该有的实体完整性、参照完整性、域完整性不能漏,没有就丢分。
6、将上面的数据输入到数据库中相应的表中
这里,推荐还是用最传统的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);
同样需要注意的是,关系表的数据最后才插入。
而且,清楚地了解该字段的数据类型,不是数字,自觉补上’‘,是数字,千万别有’’
7、将数据库备份到你的文件夹下,命名为backupInfo
备份,也就是几分钟的事,如下图,右击要备份的数据库,选择“任务”->“备份”
删除原有的默认备份路径之后,添加自定义的路径。
选好路径之后,自己写好备份文件名,注意带上后缀名,
好,这个大题,至此做完,最好能够在15分钟之内做完。
下面进入到核心的C#编程,建议这个SQL Server Management Studio Express别关。因为按照现在市场上软件编程MVC的思想,都是在数据库先组织好查询数据->推到相应的编程语言,这里是C#窗体中->再组织好数据,打印出来,一会儿自然还要多次用到SQL Server Management Studio Express
二、查询(包含连接数据库):
输入公司号,查询员工信息,按工资降序
查询各公司的人员数量并列出公司名、员工数
1、新建项目
vs2022的图示
2、新建1个类:右击项目–添加–新建项 命名为 DB.cs: 用来数据库的连接的DB.cs
DB.cs的内容:
using System;
using System.Collections.Generic;
using System.Text;
using System.Data;//DataTable用到
using System.Data.SqlClient;//一系列的数据库操作类用到
namespace WindowsFormsApp2checkonly
{
class DB : IDisposable
{
private SqlConnection sqlConnection;
public DB()//私有无参构造函数
{
sqlConnection = new SqlConnection(@"server=.\SQLEXPRESS;database=SCNT;Trusted_Connection=SSPI;");
//sqlConnection = new SqlConnection(@"server=.\SQLEXPRESS;uid=;pwd=;database=SCNT;");//sqlserver身份验证-用户密码版
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()方法主要用途是释放非托管资源。
}
}
}
3、窗体设计:
TabControl1自带两个页面:tabPage1、tabPage2
tabPage1:构件顺序:From1(自动)–TabControl1–label1–listview1–combobox1–button1–Textbox1–button2
注意:点击事件与按钮绑定的方式的两个方法:一个是直接双击按钮跳转写代码,一个是手动绑定如图:
tabPage2构件顺序:listview2–label2
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;//用到了正则表达式
using static System.Windows.Forms.VisualStyles.VisualStyleElement;
using WindowsFormsApp2checkonly;
namespace WindowsFormsApp2checkonly
{
public partial class Form1 : Form
{
DB db;
public Form1()
{
InitializeComponent();
db = new DB();
}
private void Form1_Load(object sender, EventArgs e)
{
//查询1-1
//加载现有的员工号、给下拉列表用
DataTable table = db.getBySql(@"select [CmpNo] from [COMPANY]");
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-2
//
//生成表头
listView2.Columns.Add("公司号", listView1.Width / 2 - 2, HorizontalAlignment.Left);
listView2.Columns.Add("员工数", listView1.Width / 2 - 2, HorizontalAlignment.Left);
//表的内容
table = db.getBySql(@"select CmpNo,count(CmpNo) from [WORKS]" +
" group by [CmpNo]");
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界面一次性绘制。
}
//1-1的下拉列表插查询
private void button1_Click(object sender, EventArgs e)
{
listView1.Clear();
//生成表头
listView1.Columns.Add("公司号", listView1.Width / 6 - 1, HorizontalAlignment.Left);
listView1.Columns.Add("员工号", listView1.Width / 6 - 1, HorizontalAlignment.Left);
listView1.Columns.Add("员工姓名", listView1.Width / 6 - 1, HorizontalAlignment.Left);
listView1.Columns.Add("性别", listView1.Width / 6 - 1, HorizontalAlignment.Left);
listView1.Columns.Add("年龄", listView1.Width / 6 - 1, HorizontalAlignment.Left);
listView1.Columns.Add("工资", listView1.Width / 6 - 1, HorizontalAlignment.Left);
//表的内容
DataTable table = db.getBySql(@"select [WORKS].[CmpNo],[EMPLOYEE].[EmpNo],[EMPLOYEE].[EmpName],[EMPLOYEE].[EmpSex],[EMPLOYEE].[EmpAge],[WORKS].[Salary] " +
" from [EMPLOYEE],[WORKS]" +
" where [EMPLOYEE].[EmpNo]=[WORKS].[EmpNo]" +
" and [WORKS].[CmpNo]='" + comboBox1.Text + "'" +
" order by [WORKS].[Salary] desc");
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界面一次性绘制
}
//1-2的输入文字 查询
private void button2_Click(object sender, EventArgs e)
{
listView1.Clear();
//生成表头
listView1.Columns.Add("公司号", listView1.Width / 6 - 1, HorizontalAlignment.Left);
listView1.Columns.Add("员工号", listView1.Width / 6 - 1, HorizontalAlignment.Left);
listView1.Columns.Add("员工姓名", listView1.Width / 6 - 1, HorizontalAlignment.Left);
listView1.Columns.Add("性别", listView1.Width / 6 - 1, HorizontalAlignment.Left);
listView1.Columns.Add("年龄", listView1.Width / 6 - 1, HorizontalAlignment.Left);
listView1.Columns.Add("工资", listView1.Width / 6 - 1, HorizontalAlignment.Left);
//表的内容
DataTable table = db.getBySql(@"select [WORKS].[CmpNo],[EMPLOYEE].[EmpNo],[EMPLOYEE].[EmpName],[EMPLOYEE].[EmpSex],[EMPLOYEE].[EmpAge],[WORKS].[Salary] " +
" from [EMPLOYEE],[WORKS]" +
" where [EMPLOYEE].[EmpNo]=[WORKS].[EmpNo]" +
" and [WORKS].[CmpNo]='" + textBox1.Text + "'" +
" order by [WORKS].[Salary] desc");
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界面一次性绘制
}
}
}