四、C#上位机数据库和进阶篇

相关的概念和常识

一、关于数据库
1、为什么要用数据库?
【1】大批量的、有关系的数据存储、数据检索,使用数据库非常方便。
【2】上位机从下位机采集的数据,需要定时的存储,方便后续使用。

2、数据库类型有哪些?
【1】关系型数据库:SQLServer、MySql、Sqlite、Access、Oracle
【2】非关系型数据库:Redis…

3、关系型数据库有哪些特点?
【1】表格化存储。按照指定的列,创建指定的表格,统一的数据格式。
【2】关系化存储。通过表内和表之间创建约束和关联来防止数据错误。后期修改会有效率,更灵活
【3】海量化存储。

4、数据库实体概念
【1】实体表示要存储的一组有关系的数据,对应数据表中就是一条数据。
【2】数据库实体,后面要和C#中的“实体类”做对应关系的转化。

5、数据库学什么?(Express)
【1】学会安装、了解组成(客户端 + 服务端(服务))
客户端:就是数据库软件本身
服务端:在电脑的 服务 能查到 具体看截图
在这里插入图片描述
也可以右击开始菜单 选运行 输入services.msc在这里插入图片描述在这里插入图片描述
这个就是服务,一般为自动开启

服务 和 客户端可以不在同一台电脑

【2】客户端工具基础使用(登录、密码修改、操作数据库)。
【3】基于T-SQL脚本创建、修改、查询、维护数据库。
【4】高级SQL编程。(基础掌握)

6、SQL是什么?
【1】结构化查询语言(Structured Query Language)是一种标准的数据库编程语言。
【2】T-SQL(Transact-SQL,是Microsoft SQL Server 上的增强版)

二、安装数据库

1、常用版本:SqlServer2012、SqlServer2019
2、版本说明:Express版本(专门用来学习免费使用,其他都收费)
3、启动服务:通过计算机管理—>服务(双击启动、关闭)
4、关于实例:数据库的实例,就是数据库服务的名称,安装的时候,如果以前没有装过其他版本的数据库,安装的时候,可以用默认实例,也可以用命名实例。如果以前装过其他的版本,只能用命名实例。因为实例名称不能重复。
5、命名实例:电脑名称/实例名称 比如:THINGER/SQLExpress

特别注意:《命名实例》和《默认实例》千万不要搞错。

安装后在这里打开客户端软件:
在这里插入图片描述
三、登录数据库

1、Windows身份验证:拥有最高权限。需要两个条件
【1】服务器名称:默认实例、或命名实例。
默认实例:可以用“.”来代替,也可以直接用“计算机名称”.
命名实例:必须用完整的《计算机名称\实例名称》
【2】服务必须开启。

记住:只能是本地计算机。(客户端和服务都在同一台电脑 为本地)

2、SQLServer身份验证:sa(超级管理员)拥有最高权限。需要3个条件。
【1】服务器名称。
【2】用户名。(现阶段学习都用sa)
【3】密码。(安装的时候设置好,如果忘记了,需要重新更新)

记住:我们开发中,一般都是用SQLServer身份验证。可以是本地,可以是局域网,或者云服务器远程连接。

3、开启SQLServer身份验证的步骤(如没开启要用windows身份验证登录)
【1】启用SQLServer和Windows身份验证模式。(右键)
在这里插入图片描述

【2】开启sa账号。状态选项卡:授予+已启用(双击sa)
在这里插入图片描述

【3】修改sa密码。常规选项卡:重新修改密码 (掩码长度可以无视和密码位数无关)
在这里插入图片描述

【4】重启SQLServer服务。两种方式:直接找到服务,停止后再启动。
或,右键点击《对象资源管理器》根节点,选择“重新启动”即可。
在这里插入图片描述

4、远程登录数据库 (服务器)
【1】什么是远程?局域网内的其他计算机上的数据库或者云服务器。
【2】数据库所在计算机必须开启TCP/IP协议。
在这里插入图片描述
在这里插入图片描述

【3】必须使用SQLServer身份验证。(上面讲过)
【4】默认实例必须使用“IP地址“;命名实例必须使用“IP地址/实例名”

局域网内192.168.1.*** 能正确访问并固定的IP地址

服务器(广义:只要这个计算机对外提供的信息共享;狭义:专指代用来对外提供某种数据服务的计算机)

四、登录常见问题

1、实例错误。解决方法:

【1】本地连接
第一、检查服务是否打开。
第二、确定是命名实例还是默认实例。并且保证实例名称必须写正确。

【2】远程连接
第一、按照本地连接检查远程服务开启和实例名称是否正确。
第二、检查TCP/IP协议是否打开。
第三、防火墙是否关闭。 或者单独放行 1433
第四、远程计算机是否允许远程连接等。

同时保证物理的网络畅通!

2、用户‘sa’登录失败。解决方法:
sa密码错误。改成正确的密码。

3、用户‘sa’登录失败。原因:该账户被禁用。
用windows身份验证登录,然后开启sa账号即可。

4、其他与登录相关的问题。解决方法:

按照sa开启的4个步骤逐个修改,其次把TCP/IP协议打开即可。

五、基于T-SQL创建数据库

1、认识企业管理器(就是客户端)
新建查询:可以输入命令脚本实现对数据库的任何操作

2、系统数据库的分类(不能乱动)
【1】master数据库:数据库的数据库,保存其他数据库的信息。
【2】model数据库:模板数据库。
【3】msdb数据库:用来备份等使用的数据库。
【4】tempdb数据库:临时数据库,用于存储SQL程序中产生的临时表。

3、用户数据库文件组成
【1】mdf:主数据文件。必须有,且只能有一个。
【2】ndf:次要数据文件。可以没有,可以有多个。用来扩展存储。
【3】ldf:日志文件。至少有一个,可以有多个。

4、使用T-SQL创建数据库的步骤:

【1】确定数据库的名称;数据库保存到哪里,创建好D:\DB文件夹开始创建数据库。
【2】关于保存文件的路径中的文件夹(DB文件夹内的文件夹),要提前创建好,并且添加everyone权限,如果没有这个权限,可能会出现“拒绝访问”这样的错误。在这里插入图片描述

【3】实现步骤:(参考源码和视频)
1、登录和连接数据库服务端
2、新建查询:出现文本编辑区

use master--当前数据库指向master数据库  表示下面操作是针对master数据库完成的
go--语句结束

--判断当前数据库是否在master数据库中已经存在
if exists(select *from sysdatabases where name='MISDB')
drop database MISDB --删除数据库
go

--创建数据库
create database MISDB --数据库名称MISDB
on primary--主文件组
(
	name='MISDB_Mdata',--数据库文件的逻辑名称(数据库服务内部使用的)
	filename='D:\DB\MISDB_Mdata.mdf',--存储文件的绝对路径,文件夹名不能特殊符号
	size=20MB,--数据库文件初始大小
	filegrowth=1MB--当数据超过文件大小的时候自动增长量,不能太小,频繁增长影响性能
),--主文件和次要文件之间用,
( --次要数据文件(可以有多个,也可以没有)
	name='MISDB_ndata',--数据库文件的逻辑名称(数据库服务内部使用的)
	filename='D:\DB\MISDB_ndata.ndf',--存储文件的绝对路径,文件夹名不能特殊符号
	size=20MB,--数据库文件初始大小
	filegrowth=1MB--当数据超过文件大小的时候自动增长量,不能太小,频繁增长影响性能
)
log on--日志文件至少1个
(
	name='MISDB_log1',--数据库文件的逻辑名称(数据库服务内部使用的)
	filename='D:\DB\MISDB_log1.ldf',--存储文件的绝对路径,文件夹名不能特殊符号
	size=2MB,--数据库文件初始大小
	filegrowth=1MB--当数据超过文件大小的时候自动增长量,不能太小,频繁增长影响性能
),
(
	name='MISDB_log2',--数据库文件的逻辑名称(数据库服务内部使用的)
	filename='D:\DB\MISDB_log2.ldf',--存储文件的绝对路径,文件夹名不能特殊符号
	size=2MB,--数据库文件初始大小
	filegrowth=1MB--当数据超过文件大小的时候自动增长量,不能太小,频繁增长影响性能
)
go

在这里插入图片描述
.sql 文件就是操作数据库的指令代码文件。如果在其他计算机使用只需要打开数据库,创建好指定的路径,课程推荐的路径是D\DB,打开执行这个.sql文件即可自动创建好操作好所有数据库文件指令安排的工作。 .sql 文件可直接拖拽到数据库客户端显示编辑。

如果别人给的数据库文件没有.sql文件 ,可以在 数据库软件内数据库服务端右击数据库选择 附加 添加 .mdf .ndf ,ldf 文件。
在这里插入图片描述在这里插入图片描述
在这里插入图片描述

注意:对数据库删除要在SQL软件内执行,不然执行指令因为搜不到文件会报错,指令执行完成后要在目录刷新才会显示。

SQLServer的数据类型和约束

第一、文本类型。这个是数据库中用的最多的,包括任意字母、符号或数字、字符的组合,主要有下面的六种:
(1)char: 固定长度的非Unicode字符数据,最大长度为8000个字符。 char(2)
(2)varchar: 可变长度的非Unicode数据,最大长度为8000个字符。 varchar(20)
(3)text:存储长文本信息,最大长度为231-1(2147483647)个字符。
(4)nchar:固定长度的Unicode数据,最大长度为4000个字符。
(5)nvarchar:可变长度的Unicode数据,最大长度为4000个字符。
(6)ntext:存储可变长度的长文本, 230-1(1073741823)个字符。
Unicode是国际组织制定的可以容纳世界上所有文字和符号的字符编码方案。
注意:带n的数据类型长度是不带n的两倍。比如nchar(1)和char(2)长度相同

第二、整数类型。通常包括下面4个:
(1)bigint: 占用8个字节,可表示范围:-263~263-1之间的整数。相当于C#里面64位
(2)int: 占用4个字节,可表示范围:-2³¹~2³¹-1之间的整数。
(3)smallint: 占用2个字节,可表示范围: -215~215-1之间的整数。
(4)tinyint: 占用1个字节,可表示范围:0 ~255之间的整数。

第三、精确数字类型。
(1)decimal: -10³8~10³8-1之间的固定精度和小数位的数字。
(2)numeric: 功能等同于decimal
写法:decimal(整数位数,小数位数)和numeric(整数位数,小数位数)
默认:如果不指定位数,默认18位整数,0位小数

第四、近似数字(浮点)类型。
(1)float[(n)] 表示范围:-1.79E+308 ~ 1.79E+308(1.79乘以10的308次幂)
n表示精度,在1-53之间取值,当n在1-24之间时,精度为7位有效数字,占用4个字节;当n在25-53之间时,精度为15位有效数字,占用8个字节。
(2)real表示范围:-3.40E+38 ~3.40E+38占用4个字节存储空间,相当于float(24)。

第五、日期类型。
(1)datetime:允许的范围1753-1-1至9999-1-1, datetime精确到3/100秒。
(2)smalldatetime:允许的范围1900-1-1至2079-6-6,smalldatetime精确到1分钟。
格式说明:分隔符数字方式:2013-08-20或08/20/2013;纯数字方式:08202013; 英文数字方式:Aug 20,2013;注意问题:日期在使用的时候需要使用单引号(‘’)括起来。

第六、货币类型。
(1)money:货币数值介于-263与263-1之间,精确到货币单位的千分之一。
(2) smallmoney: 货币数据介于-214748.3648与-214748.3648之间,精确到货币单位的千分之十。

第七、位类型。
bit:表示“是/否”类型的数据。(用0,1 / true、false)。

第八、二进制类型。
(1)binary:固定长度的二进制数据,最大长度为8000个字节。
(2)vbinary:可变长度的二进制数据,其最大长度为8000个字节。
(3)image:可变长度的二进制数据,其最大长度为231个字节。
应用场合:可存储图片。

数据约束
我们知道了数据类型后,还不能马上创建数据表,就像我们盖房子一样,有了砖石瓦块不能马上施工,还得要知道怎么设计的,具体有什么要求,这样才能盖出好房子。
为什么要使用约束呢?约束就是对表中字段值是否符合数据规范的一种强制性检查。通过各种检查保证用户输入和修改的数据的正确性、统一性。数据的约束通常有下面的几种:

第一、类型约束。这种约束是直接通过数据类型限制的,比如考试成绩要求是整数,当我们设置一个表的字段值是整数时,你输入其他的字符串就无法输入;同理,如果约束的是时间类型,你输入整形也是不可以的。

第二、检查约束。比如,我们定义了年龄字段,类型是整形,那用户是不是可以写200呢?对应数值类型的肯定是没问题。但是200是不符合实际的要求,这时候我们就可以通过检查约束人的年龄是1-100或其他的范围。再比如身份证我们要求是18位,可以设置一个检查约束,要求输入的位数必须是18位,否则就报错。检查约束的形式还是很多的,大家慢慢积累。

第三、非空约束。顾名思义就是这个字段不能为空,插入数据的时候必须要有数据。

第四、主键约束。一个数据表必须要有一个主键列。比如在部门表中,我们要把DepartmentId设置为主键,首先,主键强制非空,其次能够保证不能重复,最后数据在物理存储上是遵循主键的索引。
所以,主键在数据表中非常重要,同时主键作为实体的唯一标识也是实体之间相互区分的重要标志。
在这里插入图片描述

第五、外键约束。先举一个例子,比如我们去银行办理银行卡,必须要保存你的身份证号,如果身份证不正确是无法办理的,因为银行的系统中使用的身份证ID是参考了国家相关数据库系统中身份证的ID,这个就是一个典型的“外键约束”。也就是银行用的身份证ID必须来自与国家系统中的身份证ID,这样就能保证你的身份证ID在任何地方使用的时候都是一样的。如果我们把国家系统身份证信息表作为主键表的话,银行卡的身份证ID就是外键表,外键约束就是这么来的。但是我们这里说的外键约束,一般都是在一个数据库内,不同表之间的关联约束。
再比如在前面展示过的员工数据表中的DepartmentId和PostId这两个列的值就必须是来自前面主键表Department和Post中对应的字段值。如果在员工表中插入的外键值在主键表中没有,就会出现外键约束错误。外键约束在关系型数据库中非常重要。
在这里插入图片描述
当然外键约束还有另外一个重要作用那就是防止出现数据冗余和不完整性。如果我在员工表中不使用外键,直接用部门名称或者职位名称,然后职位表和部门表取消。试想在没有员工录入之前是不是部门信息和职位信息不存在?如果删除一个员工,对应的是职位和部门信息是不是也就没有了?实际情况是部门和职位不是随着员工的存在而存在,所以这种设计是不合理的。还有如果修改某一个部门的名称,因为在表中好几个人都是一个部门的,是不是得每个都得修改?这样就很容易出错。所以,我们把部门表和职位表独立存储,但是员工还需要用到这部分信息,所以,我们通过外键关联就能保证信息的完整。

注意:编写脚本窗口权限低于资源管理器。
圈上一部分命令代码可以单独执行这部分代码

SQLServer数据表的创建

18.2.1 建表的语法规范
SQLServer数据表的创建语法非常简单,基本规范如下:
create table 数据表名称
(
字段1名称 数据类型 列的特征,
字段2名称 数据类型 列的特征,

)
go
注意最后这个go批处理语句必须要有。
18.2.2 列的特征包括的内容
(1)是否为空(NULL):在输入数据时,数据库的列允许为空时,可以不输入数据,否则必须输入。列是否为空要根据数据库设计的具体要求决定,对于关键列必须禁止为空。
(2)是否是标识列(标识列,就是数据库根据一定的规范自动生成编号,不需要我们输入)。
(3)是否有默认值:如果数据表的某列在用户不输入数据的时候,希望提供一个默认的内容,比如:用户如果不输入学员地址,则默认‘地址不详’。
(4)是否为主键:主键是实体的唯一标识,保证实体不被重复。一个数据表必须有主键才有意义,如果没有,则更新和删除实体都可能会出现异常。
18.2.3 建表实战
在前面我们完成了数据库的创建,接下来把当前数据表的创建脚本给大家展示出来,并结合前面我们做的铺垫,做一个分析,脚本代码如下:

use MISDB  --注意创建数据表,必须指向当前的数据库
go
if exists (select * from sysobjects where name='Department')--创建部门表
drop table Department
go
create table Department
(
     DepartmentId  int identity(10,1) primary key,--标识列
     DepartmentName varchar(50) not null    
)
go
if exists (select * from sysobjects where name='Post')--创建职位表
drop table Post
go
create table Post
(
     PostId  int identity(10,1) primary key, --标识列
     PostName varchar(50) not null    
)
go
if exists (select * from sysobjects where name='Employee') --员工表
drop table Employee
go
create table Employee
(
     EmployeeID  int identity(1000,1) primary key,
     EmployeeName varchar(50) not null,
	 Gender char(2) not null,
	 NowAddress nvarchar(100) default('地址不详'),   --默认约束
	 IdNo char(18) not null check (len(IdNo)=18),  --检查约束
	 WeiXinNumber varchar(20) not null,
	 PhoneNumber varchar(50) not null,
	 OtherWork nvarchar(50) null,
	 EntryDate Datetime not null,
	 PostId int references Post(PostId),   --职位编号(外键)
	 DepartmentId int references Department(DepartmentId),--部门编号(外键)	 
)
go

通过上面的代码,已经把前面所讲的内容基本都运用出来了,大家主要是以下几点:
第一、数据类型的选择。给一个字段设置数据类型后,一定要根据实际的需求规定这个字段的长度,因为你设置小了会导致数据无法添加,设置大了会造成空间浪费。这些需要大家跟着课程慢慢的积累经验。
第二、约束的使用。我们常见的有主键约束、默认约束、检查约束和外键约束,大家一定要根据你设计的数据表情况,合理的使用约束,尤其是外键约束,以前经常遇到一些人设计数据库从来不用外键,觉得开发中没有那么多繁琐的事情,但是真正应用中却出现很多无法解决的问题,因为你没有了外键约束,一但你的应用程序出现逻辑错误,或者数据库管理员直接操作数据库失误,都会造成垃圾数据的进入,导致数据一致性的破坏,大家务必重视外键约束。
第三、标识列的使用。为什么要用标识列呢?有时候一个数据表存储的实体,很难找到不重复的字段作为主键列,这时候可以选择标识列,让系统帮我们生成。比如在上面的员工数据表中员工编号,如果你在设计的时候用户需求是我们自己给员工编号,那就可以不用标识列。只要我们输入的编号是唯一的就行了。还有一种情况就是员工编号在工作中不用,仅仅是作为系统中唯一的一个ID来使用,比如后面我们设计工资表的时候,需要关联员工ID,这时候就可以使用标识列。
标识列要求必须是整数类型,或者没有小数位数的精确类型。标识列包括两部分,比如我们前面设计中用的标识列是这样的:EmployeeID int identity(1000,1) primary key, identity标识列,(1000,1)标识从1000开始生成编号,每次增加1,我们把1000叫做标识种子,这个标识种子可以是1,不能是负数,也可以是2000等,这个可以根据需要来决定即可。我在这里之所以用1000是因为一般四位数比较好记忆,而且一般的企业员工也很少超过4位数,所以企业的员工编号都是4位长度。如果我们把所有的都是从1开始,以后我们写程序的时候,可能不好区分,比如前面我在职位编号中是从10开始的,我看到10、11这种编号就会想到应该是职位编号,当然部门编号我也用了10开始,因为部门和职位的个数基本都是两位数以下,我是这样来分类的,你也可以把部门编号设置为100开始。至于说后面的增量,一般都是1。关于标识列,请大家还要注意下面的问题:
(1)有标识列的数据表被删除某一行时,数据库会将该行空缺,而不会紫自动填补。
(2)标识列由系统自动维护,用户既不能自己输入数据,也不能修改数值。
(3)标识列可以同时定义为主键,也可以不定义为主键,根据需要决定。
第四、go批量处理语句。go是批处理的标志,表示SQL Server将这些SQL语句编译为一个执行单元,提高执行效率。 一般是将一些逻辑相关的业务操作语句放在同一批中,这完全由业务需求和代码编写者决定。go是SQLServer的批处理命令,只有代码编辑器才能识别并处理,编辑其他应用程序就不能使用该命令。由于每个批处理之间是独立的,因此,在一个批处理出现错误时,并不会影响其他批处理中SQL代码的运行。

SQLServer数据表数据操作

18.3.1 插入实体的基本语法和示例
数据表创建完毕后,就可以添加数据了。下面是SQLServer使用脚本插入数据的基本语法规范:
insert [into] <表名称> [列名列表] values <值列表>
这里的中括号表示可选的,但是为了统一规范,我建议大家都要写上,如果不写into在Access数据库中就不行。不写列名就得要求所有的列你都要插入值,我们有时候插入数据不见得所有列都有值,这就是矛盾,所以建议大家把可选的都写出来,也方便后面维护。下面看两个示例:

insert into Department(DepartmentName)values('开发部')
insert into Employee(EmployeeName, Gender, NowAddress, IdNo,WeiXinNumber, PhoneNumber,
OtherWork,EntryDate,PostId,DepartmentId)values ('Kiter10','男','天津','
123226199012111510','thinger01','13600001201','暂无','2020-01-01',10,10)

这个是两个标准的插入SQL语句。需要注意的问题如下:
(1)“列名个数”必须等于“对应值的个数”。也就是你写了5个列名称,必须有5个对应的值,多了不行,少了不可。
(2)非值类型的数据,必须放在单引号内。比如字符串、日期等都要加单引号。
(3)数据值的类型必须与定义的字段类型一致。比如你用的是int类型,就必须提供整数,你用日期类型,就必须是日期,否则会报错的。
18.3.2 实体批量插入和测试数据及脚本的保存
在实际开发中,作为软件开发者,我们通常在创建完数据库和数据表之后,要自己添加测试数据,有的人通过企业管理器去操作,那个是很麻烦的。偶尔可以用,因为测试的时候,不是在一台机器,把测试数据放到脚本中,特别方便别人使用。插入测试数据的时候,经常会一张表有很多数据,如果都一条条的写insert就非常麻烦,其实同时插入多条数据我们可以用如下的方法简化:
insert into Department(DepartmentName)values(‘开发部’),(‘测试部’),(‘实施部’),(‘财务部’),(‘人事部’) 这样就可以把多条数据之间插入到表中了。下面把所有的测试数据给大家贴出来,供大家参考:

use MISDB
go
--添加测试数据
insert into Department(DepartmentName)values('开发部'),('测试部'),('实施部'),('财务部'),('人事部')
insert into Post(PostName)values('软件工程师'),('测试工程师'),('实施工程师'),('财务经理'),('人事经理')
insert into Employee(EmployeeName, Gender, NowAddress, IdNo,
WeiXinNumber, PhoneNumber,OtherWork,EntryDate,PostId,DepartmentId)values
('Kiter10','男','天津','123226199012111510','thinger01','13600001201','暂无','2020-01-01',10,10),
('Kiter11','男','北京','123226199012111511','thinger02','13600001202','暂无','2020-01-02',11,11),
('Kiter12','男','上海','123226199012111512','thinger03','13600001203','暂无','2020-01-03',12,13),
('Kiter13','男','广州','123226199012111513','thinger04','13600001204','暂无','2020-01-04',10,10),
('Kiter14','男','苏州','123226199012111514','thinger05','13600001205','暂无','2020-01-05',12,12),
('Kiter15','男','南宁','123226199012111515','thinger06','13600001206','暂无','2020-01-06',10,10),
('Kiter16','男','德州','123226199012111516','thinger07','13600001207','暂无','2020-01-07',11,11),
('Kiter17','男','衢州','123226199012111517','thinger08','13600001208','暂无','2020-01-08',12,12),
('Kiter18','男','西安','123226199012111518','thinger09','13600001209','暂无','2020-01-09',10,10),
('Kiter19','男','咸阳','123226199012111519','thinger10','13600001210','暂无','2020-01-10',11,11),
('Kiter20','男','沈阳','123226199012111520','thinger11','13600001211','暂无','2020-01-11',14,14)

以上方法,请大家自行测试完成。也就是到现在我们已经完成一个完整的数据库脚本的编写。那这个脚本如何保存呢?其实非常简单,我们只需要点击查询分析器上面的工具栏中的“保存”按钮即可。
然后弹窗另存为对话框,输入一个名称,比如我授课用的名称是“MISDB.sql”,这个扩展名不要修改。关闭数据库管理系统后,下次打开,可以直接把这个脚本拖放到右边就可以了。
在这里插入图片描述
如果是其他电脑,拖放过来后,直接执行脚本,只要数据库创建路径没问题,就能直接完成数据库的迁移,非常方便。

18.3.3 查询实体
插入的数据我们怎么查看呢?这就涉及到数据的查询,SQL查询的语法规范如下:
select <列名> from <源表名> [where <查询条件>]
示例1:select * from Department 这个*号表示所有的字段,结果如下:在这里插入图片描述
示例2:select EmployeeId,EmployeeName, Gender, NowAddress, IdNo,PhoneNumber, PostId, DepartmentId from Employee在这里插入图片描述
示例3:select EmployeeId,EmployeeName, Gender,IdNo from Employee where Gender=‘男’ and PostId=10在这里插入图片描述
需要大家注意的是,写SQL语句的任何部分都要用“英文半角”状态,否则就出错。包括关键字和字段名之间的空格,很多人发现有语法错误,却不知道是什么原因,就是因为全角问题。再有,SQLServer写脚本提示没有VS那么强大,大家不要要求过于苛刻。

18.3.4 T-SQL中的运算符
在学习C#编程语言的时候,我们已经学会了运算符,在T-SQL中的运算符也是类似的,请大家记住下面的运算符号:
运算符 具体含义
= 等于

  	大于

< 小于

= 大于等于
<= 小于等于
!= 不等于(非)

更新实体
语法规范:update <表名> set <列名 = 更新值> [where <更新条件>]
特别提示:使用更新语句,一般都会和where条件配合,没有where条件会导致整个数据表更新,非常危险,还有就是前面我们用的drop删除表或者数据库,以及我们下面讲的delete删除,也要特别谨慎使用,只有在数据库开发测试阶段可能会偶尔用,实际生产数据库千万要慎重,否则你会给企业造成重大损失!更新的示例如下:
update Employee set EmployeeName=‘Topy10’,Gender=‘女’ where EmployeeId=1000
select * from Employee where EmployeeId=1000

在这里插入图片描述
删除实体
语法规范:delete from <表名> [where <删除条件>]
示例如下:
delete from Employee where EmployeeId=1009
然后执行查询:select * from Employee 发现1009的记录已经被删除。讲到这里,我们对T-SQL基础的语句就基本掌握了,这些都是最简单的,实际开发中,我们用的更多的是查询,所以接下来我们搞一个常用的查询专题。

18.4 SQLServer各种常用查询
18.4.1 内连接查询
在查询中,我们经常会从多个表中同时查询数据,这时候就需要用到表的连接查询,比如我们在员工表中执行查询返回的数据是这样的:

select EmployeeId,EmployeeName, PhoneNumber,PostId,DepartmentId from Employee

在这里插入图片描述
表中因为外键关联的两个字段是PostId和DepartmentId,在实际查询中需要得到部门名称和职位名称,这时候查询该如何写?方法是将当前的表中的两个外键和对应的两个主键表中的主键关联起来查询。脚本如下:

select EmployeeId,EmployeeName, PhoneNumber,Employee.PostId,Employee.DepartmentId, PostName,DepartmentName from  Employee
inner join Department on Department.DepartmentId=Employee.DepartmentId
inner join Post on Post.PostId=Employee.PostId

在这里插入图片描述
需要注意的问题:
第一、inner join 用来连接要关联的主键表,on 后面的就是主键表的主键和外键表的外键,如果有多个表关联,可以用多个inner join 。
第二、查询selet后面的字段,如果在主键表和外键表中都存在的字段,必须显示的写出表的名称,比如Employee.PostId和Employee.DepartmentId ,如果没有表的名称,这些字段在两个表中都有,查询语句就会出现错误提示你“列不明确”。
第三、查询的where条件,如果有的话写到最后就可以了。

改变列的名称(可改成中文):

select EmployeeId,姓名=EmployeeName, PhoneNumber,PostId,DepartmentId from Employee

或者

select EmployeeId,EmployeeName as 姓名, PhoneNumber,PostId,DepartmentId from Employee

18.4.2 常用聚合查询
在开发中,我们有时候经常会遇到查询总数、求最大值、最小值、平均值等聚合函数的使用。
第一、求总数:select count() from 表的名称 where 条件
第二、求平均值:select avg(字段名称) from 表名称 where 条件;求最大值和最小值对应的函数就是Max和Min。示例代码和结果如下:
–求总数
select 员工总数=count(
) from Employee
–最大值
select 编号最大值=max(EmployeeId) from Employee
–最小值
select 编号最小值=min(EmployeeId) from Employee
–平均值
select 编号平均值=avg(EmployeeId) from Employee
在这里插入图片描述
讲到这里我们对SQLServer的基础学习基本就可以了,后面大家就可以进入到C#如何访问数据库的问题,就是ADO.NET相关知识,也是非常重要的。数据库的其他知识,大家根据自己的需要再慢慢扩展学习即可,一开始不用花太多时间去专门研究,等基础项目都会做了再进一步研究即可。

包含有数据库文件 using System.ComponentModel; using System.Data; using System.Data.SqlClient; using System.Drawing; using System.Linq; using System.Text; using System.Windows.Forms; namespace WindowsFormsApplication10 { public partial class Form1 : Form { int id = 0; public Form1() { InitializeComponent(); radioButton1.Checked = true; } private void button1_Click(object sender, EventArgs e) { if(radioButton1.Checked==true) if (IsUserIdentify() == true) { id = 1; Form2 form1 = new Form2(id); form1.Show(); this.Visible = false; } else { MessageBox.Show("用户名或密码错误"); } if (radioButton2.Checked == true) { Form2 form = new Form2(); form.Show(); this.Hide(); } } private void button2_Click(object sender, EventArgs e) { this.Close(); } private void textBox1_TextChanged(object sender, EventArgs e) { } private void domainUpDown1_SelectedItemChanged(object sender, EventArgs e) { } private void domainUpDown2_SelectedItemChanged(object sender, EventArgs e) { } private void domainUpDown1_SelectedItemChanged_1(object sender, EventArgs e) { } private void listBox1_SelectedIndexChanged(object sender, EventArgs e) { } private void domainUpDown1_SelectedItemChanged_2(object sender, EventArgs e) { } private void menuStrip1_ItemClicked(object sender, ToolStripItemClickedEventArgs e) { } private void Form1_Load(object sender, EventArgs e) { } private void radioButton1_CheckedChanged(object sender, EventArgs e) { } private void radioButton2_CheckedChanged(object sender, EventArgs e) { textBox1.Text = "顺港"; textBox2.Text = "123123"; } private void textBox2_TextChanged(object sender, EventArgs e) { } private bool IsUserIdentify() { SqlConnection Conn = new SqlConnection("Data Source=.;Initial Catalog=book;Integrated Security=True"); Conn.Open(); string sql = "SELECT Name,PassWord FROM Admin WHERE Name='" + this.textBox1.Text + "'and PassWord='" + this.textBox2.Text + "'"; SqlCommand Cmd = new SqlCommand(sql, Conn); SqlDataReader reader = Cmd.ExecuteReader(); if (reader.Read()) { return true; } else { return false; } } } }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值