SQLServer数据库操作基础.ppt
SQL常用的语句以及建表,1.首先我们来认识一下,ASP.NET的整个访问过程是怎么样的?过程:客户端的浏览器向Web服务器提出ASP.NET页面请求(包括数据库的操作),服务器将把该页面由Asp.dll文件进行解释,并在服务器端运行,完成数据库的操作,再把数据库操作的结果生成动态的网页返回给浏览器,浏览器再将该网页内容显示在客户端。总结:客户端(页面请求)服务器(服务端)页面解释(服务端)运行,完成数据操作生成动态网页(响应)客户端这种就是典型的B/S(Browser/Server,浏览器/服务器)模型:客户端(请求)服务器(响应)客户端2.建表过程?创建数据库建表在表中加字段(也就是列)字段中设置主键(1)什么叫主键?(区分每一行的数据)主键就是数据行的唯一标识。不会重复的列才能当主键。一个表可以没有主键,但是会非常难以处理,因此没有特殊理由表中都要设定主键。主键有两种选用策略,业务主键和逻辑主键。业务主键是使用有业务意义的字段做主键,比如身份证号,银行账号等;逻辑主键是使用没有任何业务意义的字段做主键,完全给程序看的,业务人员不会看地数据。因为很难保证业务主键不会重复,(身份证重复),不会变化(账号升位),比如说电话号码,前面加个8,就找不到对应的人了。因此推荐用逻辑主键。(2)表间关联、外键(Foreign key)(具体怎么查询联接在一起没研究过)当有相同的记录列时,把这些列放在一个表中,然后通过编号关联,这时就要建立两个表。一个是设编号为主键的表1,另一个是含有编号的表2(这个编号就叫做外键),两个表的编号是一样的。表2的唯一字段(编号)关联着表1,这个字段就是指向这个表1主键的外键。如下图:(3)常用的字段类型bit:可写false和true char(10):可写入10个字符 int:可写入(32位)整数bigint:可写入(64位)整数(这里的32和64是说可写入的整数值从0到232/64-1)(可以用c#里的int.MaxValue查看它最大能容纳多大的值)nvarchar(50):含有中文的字符串 nvarchar(Max):比如写入不知字数文章字符串,Varchar(50):不含中文的字符串Char(n)不足长度n的部分用空格填充Varchar:var:variable可变的注意:比如登陆界面的用户名和密码,就不要用char(n),这样会得不到正确的数据,所以数据正好是长度n就用char(n),否则就用varchar或者nvarchar。(4)主键数据类型int(或bigint)+标识列(自动增长字段);Uniqueidentifier(又称Guid,UUID);添加自增列的方法:在设计视图里找到标识,选择是,标识递增量里改就行了。注意:一个表只能有一个标识字段(自增列),用标识列实现字段自增可以避免并发(同时有两个人访问这个记录)等问题,用标识列的字段在insert的时候不能指定主键的值。Guid算法是一种可以产生位移标识的高效算法,它使用网卡MAC地址、纳秒时间、芯片ID码等算出来的,这样保证每次生成的Guid永远不会重复,无论是同一个计算机上还是不同的计算机。在公元3400年以前产生的Guid任何其他产生过的Guid都不相同。SQLserver中生成Guid的函数newid(),Net中生成Guid的方法:Guid.NewGuid(),返回Guid类型。,优缺点:int自增字段的优点:占用空间小,无需开发人员干预、易读;缺点:效率低(在数据库中运行);数据导入导出的时候很痛苦。Guid的优点:效率高,数据导入导出方便;缺点:占用空间大(也不算大,占数据库的38%)、不易读。业界主流倾向于使用Guid。比如可以给字段默认值,如Guid类型主键的默认值设定为newid(),就会自动生成,但是会自动放在任一行(按Guid排序),所以不易查询,我们一般很少这么干。3.SQL语句SQL主要分为DDL(数据定义语言)和DML(数据操作语言)两类,Create Table、Drop Table等属于DDL(改变表的结构),select、insert、update等属于DML。注意:SQL语句中字符串用单引号。SQL语句是大小写不敏感的,不敏感指的是SQL关键字和列名(即使小写,系统也会帮你更正),字符串值还是大小写敏感。创建表,删除表不仅可以手工完成,还可以执行SQL语句完成,在自动化部署,数据导入中用的很多。(1)单表查询Select from 表名“*”表示表中所有的字段,例:select*from t_student;操作字段例:select t_name 姓名,t_number 学号 from t_student;注意:各字段用“,”分隔,上例中字段名后面用空格分隔的是该字段对应的别名。对字段执行某些运算例:select t_score+5 from t_student;这种方式操作,只能改变显示的内容,并不会改变存储在表中的数据。(2)操作记录(也叫做操作行)筛选:Select*from 表名 where 条件;意思是选择符合条件那些记录(行)查询条件如下:比较(=,=,(不等号)确定范围(between 下限 and 上限,not between 下限 and 上限):在下限值和上限值之间确定集合(in,not in):检查一个属性值是否属于集合中的值。例:select*from t_student where t_mizu not in(汉,回);查询不是汉族和回族的学生信息字符匹配(like,not like):用于构造条件表达式中的字符匹配例:select*from t_student where t_name like 张%;查询姓“张”的学生信息,注意:使用like前的列名必须是字符串类型。在like中经常使用的有两种通配符:“_”(下划线)表示任一单个字符;“%”(百分号)表示任意长度字符。上面的例子把张%变成%张%表示查询该字段下含有张字的学生信息(记录),如果把张%变成%张表示查询该字段下以张字结尾的学生信息。逻辑运算(and,or,not):用于构造复合表达式在构造查询条件时,还可以使用逻辑运算符(and,or,not)组成复合查询。例:select*from t_student where t_scorefrom 表名 where 条件 order by asc|desc,asc|desc,通过order by来改变输出结果的排序方式。其中asc表示查询结果按照升序排序,desc指定按照降序排序。系统默认按照升序排序,中括号里这两个值可以不写。例:select*from t_student order by t_sex desc,t_number asc;按照性别降序排序的同时按照学号的升序显示。注意:由于在排序的过程中,服务器执行的时间比一般select语句执行的时间要长,因此,不是特别需要的情况下,建议少用order子句。,查询互不相同的记录:select distinct from 表名;查询不重复的数据,剔除重复的数据。集合函数前面介绍的内容都集中在从一个数据表中按照用户的要求取得一个或多个记录,如果要对表中的记录进行数据统计,就要用到集合函数。Count():统计记录个数。Avg():计算某个数值型字段值的平均值。Sum():计算某个数值型字段值的总和。Max():计算某个数值型字段值的最大值。Min():计算某个数值型字段值的最小值。在select语句中利用集合函数结合前面所讲的查询条件可以统计出用户感兴趣的信息。例如:select count(*)from t_student;统计t_student数据表中学生的人数。Select sum(t_score)from t_student;统计t_student数据表中所有学生的总分。(3)添加记录向表格中插入新的行:insert into 表名()values();这句的意思是添加值1到列1中,值2到列2中生成一条记录(行)。,表2中的列数据复制到表1中的列中(实现列的复制功能,实用)insert into 表1名()selectfrom 表2名 where 条件这句的意思是从表2中满足条件的列数据复制到表1相应的列中,并生成记录。列1对应列1,列2对应列2,列是相互对应的。注意:上面的语句哪些地方有括号,哪些地方没括号,这些都是要注意的地方。值1对应列1,值2对应列2,而且插入的数据类型也要一致。如果使用insert语句向数据表中添加记录时仅指定部分的字段,其他没有指定的字段按下面4种情况处理:如果该字段是自增列,不用管它,自己会自动增加一个新值。如果该字段有默认值,就使用默认值。如果该字段被设置成可以接受空值,而且没有默认值,该字段为空值。如果该字段不能接受空值,而且没有默认值,就会出现错误。(值得注意)跨数据库复制列记录(实用):insert into 数据库名1.dbo.表1名()selectfrom 数据库名2.dbo.表2名 where 条件,(4)修改数据库中的数据记录(实用)Update 表名 set 列1=值1,列2=值2where 条件;无where子句,则表中的所有记录都将被修改。Update 表名 set 目的列=源列(提供资源的列);意思是源列的数据复制到目的列中。区别:上面这句只能在一个表中进行,而且不能生成新的记录,只是对原有的列进行数据修改,而insert语句进行复制时,可以跨数据库,跨表进行列的复制,并且生成新的记录。(5)表添加字段(列)Alter table 表名 add 列名 字段类型;Alter table 表名 drop column 列名;(6)删除数据库Drop database 数据库名;(7)删除表Drop table 表名;删除表Delete from 表名 where 条件;清空表数据,而不删除表,无where条件,删除所有记录。Truncate table 表名;快速清空数据库内指定表内容,不会保留日志。,(8)其他identify 类型的列,里面的值是自动增加的。也就是自增列类型。Select identify;查看目前增加自增列最新的值。identify是表示最近一次向具有identify属性(即自增列)的表插入数据时对应的自增列的值,是系统定义的全局变量。一般系统定义的全局标量都是以开头,用户自定义变量以开头。比如有个表A,它的自增列是id,当向A表插入一行数据后,如果插入数据后自增列的值自动增加到101,则通过select identify得到的值就是101。使用identify的前提是在进行insert操作后,执行select identify的时候链接没有关闭,否则得到的将是null值。编辑200页以后的记录,在左上角有个SQL的按钮,然后修改select top(记录数)里的记录数就可以显示了。在不删除sql server表中数据的情况下,让自增列从1开始?删除表的记录以后,如何使新记录的编号仍然从1开始?有两种方法truncate table 表名;这样不但将数据删除,而且可以重新置位identify属性的字段。(2)delete from 表名;Dbcc checkident(表名,reseed,0);重新置位identify属性的字段,让其下个值从1开始。,(9)创建表Use 数据库Create table 表名(字段名 字段属性,)例:book_id int not null primary key/值非空,并设为主键(10)空值处理数据库中,一个列如果没有指定值,那么值就为null,这个null和c#中的null不同,数据库中的null表示“不知道”,而不是表示没有,因此select null+1结果是null(比如说1号的年龄为不知道,2号的年龄为1,两者相加为不知道),因此“不知道”加1的结果还是“不知道”。Select*from T_employee where fname=null;Select*from T_employee where fnamenull;这两个例子都没有任何返回结果,因为数据库也“不知道”;原因是查询这个表中所有的fname=不知道的数据,查任何一条结果都等于false,fname里存在null不知道,不知道=不知道,所以,等不等于null都是一样的结果,就是不出结果。解决方法:SQL中使用is null、is not null来进行空值判断Select*from T_employee where fname is null;Select*from T_employee where fname is not null;,(11)限制结果集行数(主要用于分页功能)Select top 行数 列名 from 表名 order by 列名 descasc;这句语句的意思是选择表中前几行数据,再根据所选的列排序。例:select top 3*from T_employee where fnumber not in(select top 5 fnumber from T_employee order by fsalary desc)Order by fsalary desc;括号内是先查询前5的数据,然后去掉前5的数据,查询从第6开始的前三条数据。SQL server 2005 后增加了Row_number函数简化实现(没了解到)。(12)联合结果集(用于写报表比较合适)用union来连接表例:select FNumber,FName,FAge from T_Employee union select FidCardNumber,FName,FAge from T_TempEmployee注:列数相同,类型相同。基本原则:每个结合集必须有相同的列数,每个结合集的列必须类型相容(可以理解为相同)。Union合并两个查询结合集,并且将其中完全重复的数据行合并为一条。,Union因为要进行重复值扫描,所以效率低,因此如果不是确定要合并重复行,那么就用union all。两个表中的数据求和:例:select id,name from xp union all select id,name from xy union all select 0,sum(name)from(select name from xp union all select name from xy)a(13)如何将SQL Service 2008里的查询结果导出到Excel表内?查询完之后再结果栏内按Ctrl+A将结果全选,按右键选择“将结果另存为”,然后保存为“*.csv”文件,就可以用Excel打开了。或者“连同标题一起复制”(全选下),然后将结果拷贝到excel表中就可以了。(14)复制表(只复制结构,源表名:a 新表名:b)select*into b from a where 11,(15)将Excel表中的数据导入到SQL中?第一步:登录到SQL Service Management Studio;第二步:在“对象资源管理器”中右键单击“管理”,在弹出列表中单击“导入”数据;第三步:在“导入向导”对话框中单击“下一步”,进入到“选择数据源”对话框,在“数据源”列表中选择“Microsoft Excell”,同时选择相应的Excell文档,完成后单击“下一步”(一定要勾选对话框中的“首行包含列名称”,因此它是将Excell文档中的列标题为数据库表中的列项标题),也就是说第一行为SQL的列名。第四步:重新打开SQL Service Management Studio,进入到导入的数据库表,可以发现所导入的Excell文档数据。,当浏览器在请求一个Web页面是从URL开始的。下面就是过程描述:1 输入URL地址或者点击URL的一个链接2 浏览器根据URL地址,结合DNS,解析出URL对应的IP地址3 发送HTTP请求4 开始连接请求的服务器并且请求相关的内容(至于请求时怎么被处理的,这里暂时不讨论)5 浏览器解析从服务器端返回的内容,并且把页面显现出来,同时也继续进行其他的请求。当一个浏览者在浏览器地址框中打入某一个域名,或者从其他网站点击了链接来到了这个域名,浏览器向这个用户的上网接入商发出域名请求,接入商的DNS服务器要查询域名数据库,看这个域名的DNS服务器是什么。然后到DNS服务器中抓取DNS记录,也就是获取这个域名指向哪一个IP地址。在获得这个IP信息后,接入商的服务器就去这个IP地址所对应的服务器上抓取网页内容,然后传输给发出请求的浏览器。这个过程描述起来满复杂,但实际上不到一两秒钟就完成了域名-hosts-本地dns缓存-dns服务器,正确顺序是第一种 如下:本地DNS缓存 本地HOSTS文件 DNS服务器 具体如下:一台计算机访问Internet的DNS解析过程是(以访问站点为例),首先查看当前计算机的DNS缓存里有没有这条记录;如果没有,再查看当前计算机的“hosts”文件,“hosts”文件位于C:WINDOWSsystem32driversetc目录当中;如果hosts文件中没有,就接着查找当前DNS服务器里有没有这条记录;如果还是没有,看当前的DNS服务器有没有配置DNS转发器,如果配置了DNS转发器就查找它的上一级DNS服务器,如果没有配置DNS转发器,就直接查找DNS“根”服务器。查找到DNS“根”服务器后,“根”服务器将DNS请求转到“.com”域中,“.com”域再将请求转到“baidu”域中,然后在“baidu”域查找www的A记录,这样一个DNS解析过程就完成了。,varchar在SQL Server中是采用单字节来存储数据的,nvarchar是使用Unico来存储数据的中文字符存储到SQL Server中会保存为两个字节(一般采用Unico编码),英文字符保存到数据库中,如果字段的类型为varchar,则只会占用一个字节,而如果字段的类型为nvarchar,则会占用两个字节 正常情况下,我们使用varchar也可以存储中文字符,但是如果遇到操作系统是英文操作系统并且对中文字体的支持不全面时,在SQL Server存储中文字符为varchar就会出现乱码(显示为?)而且正常情况下,主机都会支持中文的环境,所以如果使用varchar来存储数据,在开发阶段是发现不了的多数情况下,在布署的时候也不会有问题但是!如果布署的主机是英文操作系统,并且不支持中文环境,那问题就出来了所有的varchar字段在存储中文的时候都会变成乱码(显示为?)而且一般情况下你不会知道这是因为你采用了错误的数据类型来存储所造成的,你会试着去装中文字体,试着去设置操作系统的语言环境这些都不能解决问题,唯一能解决问题的是把数据库字段的类型个性为nvarchar(或者nchar)对项目管理比较熟悉的朋友应该都知道,到布署阶段再来修改数据库是一个很恐怖的事情使用nvarchar的另一个非常好处就是在判断字符串的时候可以不需要考虑中英文两种字符的差别当然,使用nvarchar存储英文字符会增大一倍的存储空间但是在存储代价已经很低廉的情况下,优先考虑兼容性会给你带来更多好处的所以在Design的时候应该尽量使用nvarchar来存储数据只有在你确保该字段不会保存中文的时候,才采用varchar来存储,