教你入门Sql Server 编程

    作者:课课家教育更新于: 2018-11-20 11:11:21

      SQL Server 编程入门

          想要学好编程,就要多练习,练习也讲究方法,多参考相关资料,总结出属于自己的知识链,以达到事半功倍的效果。下面就跟随课课家小编的脚步,学习一下Sql Server的编程基础吧! 

      一、T—SQL 的组成

      1、DML(数据操作语言 Data Manipulation Language)

      查询、插入、删除和修改数据库中的数据。SELECT、INSERT、UPDATE、DELETE 等;

      2、DCL(数据控制语言 Data Control Language)

      用来控制存取许可、存取权限等。GRANT、REVOKE 等。

      3、DDL(数据定义语言 Data Definition Language)

      用来建立数据库、数据库对象和定义其列。CREATE TABLE 、DROP TABLE 等。

      4、变量说明、流程控制、功能函数

      定义变量、判断、分支、循环结构等。日期函数、数学函数、字符函数、系统函数等。

      二、库

      1、建立库

      --判断是否存在该库,如果有则删除

      USE master --设置当前数据库为 master,以便访问 sysdatabases 表

      GO

      IF EXISTS(SELECT * FROM sysdatabases WHERE name ='stuDB')

      DROP DATABASE stuDB

      --建立数据库

      CREATE DATABASE stuDB

      ON PRIMARY --默认就属于 PRIMARY 主文件组,可省略

      (

      NAME='stuDB_data', --主数据文件的逻辑名

      FILENAME='D:\\project\\stuDB_data.mdf', --主数据文件的物理名

      SIZE=5mb, --主数据文件初始大小

      MAXSIZE=100mb, --主数据文件增长的大值

      FILEGROWTH=15% --主数据文件的增长率

      )

      LOG ON

      (

      NAME='stuDB_log',

      FILENAME='D:\\project\\stuDB_log.ldf',

      SIZE=2mb,

      FILEGROWTH=1MB

      )

      GO

      2、删除库

      USE master --设置当前数据库为 master,以便访问 sysdatabases 表

      GO

      IF EXISTS(SELECT * FROM sysdatabases WHERE name ='stuDB')

      DROP DATABASE stuDB

      EXISTS()语句:检测是否存在 stuDB 数据库,如果存在 stuDB mysql教程数据库,则删除

      sysdatabases 表在 master 数据库中,保存着当前系统中所有的数据库

      三、表

      1、建表

      --判断是否存在该表,有则删除

      USE stuDB --将当前数据库设置为 stuDB ,以便在 stuDB 数据库中建表

      GO

      IF EXISTS(SELECT * FROM sysobjects WHERE name='stuInfo' )

      DROP TABLE stuInfo

      --建表

      CREATE TABLE stuInfo /*-创建学员信息表-*/

      (

      stuName VARCHAR(20) NOT NULL , --姓名,非空(必填)

      stuNo CHAR(6) NOT NULL, --学号,非空(必填)

      stuAge INT NOT NULL, --年龄,INT 类型默认为 4 个字节

      stuID NUMERIC(18,0), --身份证号

      stuSeat SMALLINT IDENTITY (1,1), --座位号,自动编号

      stuAddress TEXT --住址,允许为空,即可选输入

      )

      GO

      2、删表

      USE 库名 --将当前数据库设置为 stuDB ,以便在 stuDB 数据库中建表

      GO

      IF EXISTS(SELECT * FROM sysobjects WHERE name='表名' )

      DROP TABLE 表名

      四、约束

      1、主键(primary key)

      ALTER TABLE stuInfo

      ADD CONSTRAINT PK_stuNo PRIMARY KEY (stuNo)

      2、唯一性(uinque)

      ALTER TABLE stuInfo

      ADD CONSTRAINT UQ_stuID UNIQUE (stuID)

      3、默认填写(default('……' ) for)

      ALTER TABLE stuInfo

      ADD CONSTRAINT DF_stuAddress

      DEFAULT ('地址不详') FOR stuAddress

      4、检查(check(……))

      ALTER TABLE stuInfo

      ADD CONSTRAINT CK_stuAge

      CHECK(stuAge BETWEEN 15 AND 40)

      5、外键(foreign key(列名) references 主表名(列名))

      ALTER TABLE stuMarks

      ADD CONSTRAINT FK_stuNo

      FOREIGN KEY(stuNo) REFERENCES stuInfo(stuNo)

      6、删除约束

      ALTER TABLE 有约束的表名 DORP 约束名

      五、通配符

      通配符 解释 示例

      '_' 一个字符 A Like 'C_'

      % 任意长度的字符串 B Like 'CO_%'

      [ ] 括号中所指定范围内的一个字符 C Like '9W0[1-2]'

      [^] 不在括号中所指定范围内的一个字符 D Like '%[A-D][^1-2]'

      六、插入数据

      INSERT 表名(列名) VALUES (插入的列值)

      insert stuinfo(stuname,stuno,stuage,stuid,stuaddress)

      values('张三',001,20,100,'hello')

      1、注意事项

      A、每次插入一行数据,不可能只插入半行或者几列数据,因此,插入的数据是否有效将

      按照整行的完整性的要求来检验。

      B、每个数据值的数据类型、精度和小数位数必须与相应的列匹配。

      C、不能为标识列指定值,因为它的数字是自动增长的。

      D、如果在设计表的时候就指定了某列不允许为空,则必须插入数据。

      E、插入的数据项,要求符合检查约束的要求。

      F、具有缺省值的列,可以使用 DEFAULT(缺省)关键字来代替插入的数值。

      2、插入多行数据

      (1)对象表存在

      INSERT INTO <表名>(列名)

      SELECT <列名> FROM <源表名>

      INSERT INTO stuinfobak (stuname,stuno,stuage)

      SELECT stuname,stuno,stuage FROM stuinfo

      (Stuinfobak 表必须在数据库中存在)

      (2)对象表不存在

      SELECT (列名) INTO <表名> FROM <源表名>

      SELECT stuname,stuno,stuage INTO stuinfobak1 FROM stuinfo

      (Stuinfobak1 表必须在数据库中不存在)

      (3)插入新的标识列

      IDENTITY(数据类型,标识种子,标识增量)

      SELECT IDENTITY(数据类型,标识种子,标识增长量) AS 列名

      INTO 新表 FROM 原始表

      SELECT Students,SName,Students,SAddress,Students,SEmail,

      IDENTITY(int,1,1) As StudentID

      INTO TongXunLuEX FROM Students

      (4)插入多行内容

      INSERT INTO <表名>(列名)

      SELECT 列内容 UNION

      SELECT 列内容 UNION

      ……

      七、更新数据行

      UPDATE <表名> SET <列名 = 更新值>

      [WHERE <更新条件>]

      UPDATE Students

      SET SAddress ='某社区 22#楼 4 单元 45 号'

      WHERE SAddress = '某社区 22#楼 4 单元 45 号'

      UPDATE Scores

      SET Scores = Scores + 5

      WHERE Scores <= 95

      八、删除数据行

      1、删除指定的行

      DELETE FROM <表名> [WHERE <删除条件>]

      注意:DELETE FROM 不会只删单个字段,要删就是整行

      2、删除所有记录

      TRUNCATE TABLE <表名>

      注意:不能用于有外键约束引用的表。删除后,表的结构、列、约束、索引不变。

      九、查询

      SELECT <列名>

      FROM <表名>

      [WHERE <查询条件表达式>]

      [ORDER BY <排序的列名>[ASC(升)或 DESC(降)] ] --默认为升序

      1、查询全部的行和列

      SELECT * FROM Students

      2、查询部分行

      SELECT <列名>

      FROM <表名>

      WHERE <查询条件表达式>

      3、自定义命名查询结果中的列名

      (1)使用 AS 来命名列

      SELECT 原表中列名 AS 查询结果中显示的列名

      FROM <表名>

      WHERE <查询条件表达式>

      SELECT Stuno AS 学员编号,StuName AS 学员姓名,StuAddress AS 学员地址

      FROM stuinfo

      WHERE SAddress like '地址不详'

      (2)合并两列数据,以规定格式输出查询结果

      SELECT 原表中列名+ '.' +原表中列名 AS 查询结果中显示的列名

      FROM 表名

      (3)使用=来命名列

      SELECT 查询结果中显示的列名 = 原表中列名

      FROM <表名>

      WHERE <查询条件表达式>

      SELECT 查询结果中显示的列名 = 原表中列名+ '.' +原表中列名

      FROM 表名

      (4)查询某几列为空的行

      SELECT 列名 A

      FROM 表名

      WHERE 条件列名 B IS NULL

      显示结果:B 列为空的 A 列内容。

      (5)显示结果中加入常量列

      SELECT 列 A = SName,列 B = SAddress,'常量列内容'AS 常量列名称

      FROM Students

      SELECT 姓名=SName,地址= SAddress,'72 中' AS 学校名称

      FROM Students

      (6)限制查询结果输出的行数

      SELECT TOP 5 列名

      FROM 表名

      WHERE 条件

      显示结果:符合条件的前五行。

      (7)返回百分之多少行

      SELECT TOP 20 PERCENT 列名

      FROM 表名

      WHERE 条件

      显示结果:符合条件的行数的前 20%行。

      (8)升序排列(默认)ASC

      SELECT StudentID As 学员编号,(Score*0.9+5) As 综合成绩

      FROM Score

      WHERE (Score*0.9+5)>60

      ORDER BY Score

      (9)降序排列 DESC

      SELECT Au_Lname +'.' +Au_fName AS EMP

      From 表 A Union

      SELECT fName +'.'+ LName AS EMP

      From 表 B

      ORDER BY EMP DESC

      显示结果:混合查找两张表中的列,并按格式输出到新列中,并按新列排序输出。

      (10)按多列排序

      SELECT StudentID As 学员编号, Score As 成绩

      FROM 表名

      WHERE Score>60

      ORDER BY Score,studentID

      显示结果:先按 Score 排序,再按 studentID 排序。

      十、模糊查询

      1、LIKE

      查询时,字段中的内容并不一定与查询内容完全匹配,只要字段中含有这些内容。

      SELECT StuName AS 姓名

      FROM Stuinfo

      WHERE stuname LIKE '徐%'

      显示结果:姓为“徐”的人的名字。

      2、IS NULL

      把某一字段中内容为空的记录查询出来。

      SELECT StuName AS 姓名,StuAddress AS 地址。

      FROM Stuinfo

      WHERE StuAddress IS NULL

      显示结果:把地址栏为空的显示出来。

      3、BETWEEN

      把某一字段中内容在特定范围内的记录查询出来。

      SELECT StuNo, Score

      FROM Stumarks

      WHERE Score BETWEEN 60 AND 80

      显示结果:把分数 80>= Score >=60 的显示出来。

      4、IN

      把某一字段中内容与所列出的查询内容列表匹配的记录查询出来。

      SELECT StuName AS 学员姓名,StuAddress As 地址

      FROM Stuinfo

      WHERE StuAddress IN ('北京','广州','上海')

      显示结果:把地址在('北京','广州','上海')里的显示出来。

      十一、聚合函数

      1、SUM(求和)

      SELECT SUM(Score)

      FROM Stumarks

      WHERE 条件

      显示结果:把符合条件的 Score 求和,然后显示结果。

      2、AVG(求平均值)

      SELECT AVG(SCore) AS 平均成绩

      From Score

      WHERE Score >=60

      显示结果:把 Score >=60 的成绩求平均值,然后显示结果,显示的列名为“平均成绩”

      3、MAX、MIN(求大、小值)

      SELECT MAX (Score) AS 高分, MIN (Score) AS 低分

      From Score

      WHERE Score >=60

      显示结果:把 Score>=60 中的高分和低分显示出来。

      4、COUNT(计数)

      SELECT COUNT (*) AS 及格人数

      From Score

      WHERE Score>=60

      显示结果:把 Score 列中,>=60 的个数统计出来,然后显示统计数目。

      十二、分组查询

      1、单列分组查询

      SELECT CourseID, AVG(Score) AS 课程平均成绩

      FROM Score

      GROUP BY CourseID

      显示结果:按 CourseID 组求 Score 的平均值,然后将 CourseID 和平均值显示出来。

      2、多列分组

      SELECT StudentID AS 学员编号,CourseID AS 内部测试, AVG(Score) AS 平均成绩

      FROM Score

      GROUP BY StudentID,CourseID

      显示结果:显示所有学员的:“学员编号”(StudentID),“内部测试”(CourseID),“平均

      成绩”(AVG(Score))。如果同一 CourseID 组中出现了相同的 StudentID,则显示出来的是这一

      CourseID 组中相同的 StudentID 的平均成绩。

      3、HAVING(追加条件)

      SELECT StudentID AS 学员编号,CourseID AS 内部测试, AVG(Score) AS 平均成绩

      FROM Score

      GROUP BY StudentID,CourseID

      HAVING COUNT(Score)>1

      显示结果:显示补考学员的:“学员编号”(StudentID),“内部测试”(CourseID),“平均

      成绩”(AVG(Score))。如果同一 CourseID 组中的同一 StudentID 组中记录 Score 的次数,如果

      次数>1,则显示出来“学员编号”(StudentID),“内部测试”(CourseID),“平均成绩”(AVG(Score))。

      4、条件比较顺序

      WHERE 子句从数据源中去掉不符合其搜索条件的数据。

      GROUP BY 子句搜集数据行到各个组中,统计函数为各个组计算统计值。

      HAVING 子句去掉不符合其组搜索条件的各组数据行。

      WHERE———>GROUP BY———>HAVING

      十三、多表联接查询

      1、分类

      (1)内联接(INNER JOIN)

      (2)外联接

      A、左外联结 (LEFT JOIN)

      B、右外联结 (RIGHT JOIN)

      C、完整外联结 (FULL JOIN)

      (3)交叉联接(CROSS JOIN)

      2、多表内联结查询

      (1)建立联接

      SELECT S.SName,C.CourseID,C.Score

      From Score AS C

      INNER JOIN Students AS S

      ON C.StudentID = S.SCode

      显示结果:把 Score 表和 Students 表建立内联结,查询 C.StudentID = S.SCode 时,显示

      S.SName,C.CourseID,C.Score 的内容。

      (2)未建立联接

      SELECT Students.SName, Score.CourseID, Score.Score

      FROM Students,Score

      WHERE Students.SCode = Score.StudentID

      显示结果:同上。

      (3)多表联接查询—三表联接

      SELECT S.SName AS 姓名, CS.CourseName AS 课程, C.Score AS 成绩

      FROM Students AS S

      INNER JOIN Score AS C

      ON (S.SCode = C.StudentID)

      INNER JOIN Course AS CS

      ON (CS.CourseID = C.CourseID)

      (4)区别

      建立联接的查询速度比没有建立的快得多。

      3、多表外联接查询

      (1)左外联接

      (LEFT JOIN 或 LEFT OUTER JOIN)

      SELECT S.SName,C.CourseID,C.Score

      From Students AS S

      LEFT JOIN Score AS C

      ON C.StudentID = S.SCode

      显示结果:Students 为左表(left join)Score 为右表。左表中有的,右表中没有的显示空值

      (NULL)。

      (2)右外联接

      (RIGHT JOIN 或 RIGHT OUTER JOIN)

      SELECT Titles.Title_id, Titles.Title, Publishers.Pub_name

      FROM titles

      RIGHT OUTER JOIN Publishers

      ON Titles.Pub_id = Publishers.Pub_id

      显示结果:与左外连接相反。

      (3)完整外联接

      (FULL JOIN 或 FULL OUTER JOIN)

      显示结果:左表和右表中的所有行。当某行在另一个表中没有匹配行时,则另一个表的

      选择列为空值;如果有匹配行,则显示结果包括左右表中的所有列值。

      4、多表交叉联接查询

      (CROSS JOIN)

      交叉联接返回左表中的所有行,左表中的每一行与右表中的所有行一一组合,相当于两

      个表“相乘”。

      十四、数据库用户

      1、创建登录帐户

      (1)添加 Windows 登录帐户

      EXEC sp_grantlogin 'jbtraining\\S26301' (域名\\用户名)

      (2)添加 SQL 登录帐户

      EXEC sp_addlogin 'zhangsan', '1234'

      EXEC 表示调用存储过程,存储过程类似 C 语言的函数。

      内置的系统管理员 帐户 sa,密码默认为空,建议修改密码

      2、创建数据库用户

      USE 库名

      GO

      EXEC sp_grantdbAccess '登录帐户名','数据库用户名'

      其中,“数据库用户“为可选参数,默认为登录帐户,即数据库用户默认和登录帐户同名。

      3、给用户分配权限

      GRANT 权限 [ON 表名 ] TO 数据库用户

      权限:select、insert、update、delete、create table ……

      4、系统内置的数据库用户

      (1)dbo 用户

      A、表示数据库的所有者(DB Owner)

      B、无法删除 dbo 用户,此用户始终出现在每个数据库中

      (2)guest 用户

      A、适用于没有数据库用户的登录帐号访问

      B、每个数据库可有也可删除

      十五、T—SQL 编程

      1、变量

      (1)局部变量

      A、局部变量必须以标记@作为前缀 ,如@age。

      B、局部变量的使用也是先声明,再赋值。

      C、声明局部变量

      DECLARE @变量名 数据类型

      D、赋值

      SET @变量名 = 值

      SELECT @变量名 = 值

      (2)全局变量

      A、全局变量必须以标记@ @作为前缀,如@@version

      B、全局变量由系统定义和维护,我们只能读取,不能修改全局变量的值

      C、全局变量的类型与含义

      变 量 含 义

      @@ERROR 后一个 T-SQL 错误的错误号

      @@IDENTITY 后一次插入的标识值

      @@LANGUAGE 当前使用的语言的名称

      @@MAX_CONNECTIONS 可以创建的同时连接的大数目

      @@ROWCOUNT 受上一个 SQL 语句影响的行数

      @@SERVERNAME 本地服务器的名称

      @@TRANSCOUNT 当前连接打开的事务数

      @@VERSION SQL Server 的版本信息

      2、输出语句

      (1)print 局部变量或字符串

      结果在消息窗口以文本方式显示。

      (2)SELECT 局部变量 AS 自定义列名

      结果在网格窗口以表格方式显示。

      3、逻辑控制语句

      (1)IF-ELSE 条件语句

      IF(条件)

      BEGIN

      语句块……

      END

      ELSE

      ……

      (2)WHILE 循环语句

      WHILE(条件)

      BEGIN

      语句块……

      (BREAK)-- 跳出循环,可选语句。

      END

      (3)CASE—END 多分支语句

      CASE

      WHEN 条件 1 THEN 结果 1

      WHEN 条件 2 THEN 结果 2

      ……

      (ELSE) -- 其他结果,可选语句。

      END

      (4)GO 批处理语句

      语句 1

      语句 2

      ……

      GO -- 批处理语句的标志

      A、 批处理是包含一个或多个 SQL 语句的组,从应用程序一次性地发送到 SQL Server

      执行。SQL Server 将批处理语句编译成一个可执行单元,此单元称为执行计划。执行

      计划中的语句每次执行一条。

      B、 GO 是批处理的标志,表示 SQL Server 将这些 T-SQL 语句编译为一个执行单元,提高

      执行效率。一般是将一些逻辑相关的业务操作语句,放置在同一批中,这完全由业务需

      求和代码编写者决定。

      C、 SQLServer 规定:如果是建库、建表语句、以及我们后面学习的存储过程和视图等,

      则必须在语句末尾添加 GO 批处理标志。

      十六、高级查询

      1、简单的子查询

      SELECT * FROM stuInfo

      WHERE stuAge>( SELECT stuAge FROM stuInfo where stuName='姓名')

      (1)子查询的一般用法

      A、SELECT … FROM 表 1 WHERE 字段 1 >(子查询)。

      B、外面的查询称为父查询,括号中嵌入的查询称为子查询。

      C、UPDATE、INSERT、DELETE 一起使用,语法类似于 SELECT 语句。

      D、将子查询和比较运算符联合使用,必须保证子查询返回的值不能多于一个。

      (2)子查询替换表连接

      A、一般来说,表连接都可以用子查询替换,但有的子查询却不能用表连接替换。

      B、子查询比较灵活、方便,常作为增删改查的筛选条件,适合于操纵一个表的数据。

      C、表连接更适合于查看多表的数据。

      2、IN(NOT IN)子查询

      SELECT stuName FROM stuInfo

      WHERE stuNo IN (SELECT stuNo FROM stuMarks WHERE writtenExam=60)

      IN(在子查询范围内),NOT IN(不在子查询范围内)

      IN(NOT IN)后面的子查询可以返回多条记录,常用 IN 替换等于(=)的比较子查询。

      3、EXISTS 子查询

      IF EXISTS (子查询)

      语句……

      A、如果子查询的结果非空,即记录条数 1 条以上,则 EXISTS (子查询)将返回真(true),

      否则返回假(false) 。

      B、EXISTS 也可以作为 WHERE 语句的子查询,但一般都能用 IN 子查询替换。

      C 、EXISTS 和 IN 一样,允许添加 NOT 取反,表示不存在。

      十七、事务

      1、使用 T-SQL 语句来管理事务

      开始事务:BEGIN TRANSACTION

      提交事务:COMMIT TRANSACTION

      回滚(撤销)事务:ROLLBACK TRANSACTION

      2、判断某条语句执行是否出错

      使用全局变量@@ERROR。@@ERROR 只能判断当前一条 T-SQL 语句执行是否有错,

      为了判断事务中所有 T-SQL 语句是否有错,我们需要对错误进行累计;

      如: SET @errorSum=@errorSum+@@error

      3、事务必须具备 ACID 四个属性

      原子性(Atomicity):事务是一个完整的操作。事务的各步操作是不可分的(原子的);

      要么都执行,要么都不执行

      一致性(Consistency):当事务完成时,数据必须处于一致状态

      隔离性(Isolation):对数据进行修改的所有并发事务是彼此隔离的,这表明事务必须是

      独立的,它不应以任何方式依赖于或影响其他事务

      永久性(Durability):事务完成后,它对数据库的修改被永久保持,事务日志能够保持

      事务的永久性

      4、事务的分类

      显示事务:用 BEGIN TRANSACTION 明确指定事务的开始,这是常用的事务类型

      隐性事务:通过设置 SET IMPLICIT_TRANSACTIONS ON 语句,将隐性事务模式设置

      为打开,下一个语句自动启动一个新事务。当该事务完成时,再下一个 T-SQL 语句又将启

      动一个新事务

      自动提交事务:这是 SQL Server 的默认模式,它将每条单独的 T-SQL 语句视为一个

      事务,如果成功执行,则自动提交;如果错误,则自动回滚

      5、事务例句

      BEGIN TRANSACTION -- 开始事务

      DECLARE @errorSum INT --定义变量接收错误语句数

      SET @errorSum = 0 --初始化变量,无错误

      SQL 语句 1

      SET @errorSum=@errorSum+@@error

      SQL 语句 2

      SET @errorSum=@errorSum+@@error

      ……

      IF @errorSum <> 0 --产生错误,回滚事务

      BEGIN

      ROLLBACK TRANSACTION

      END

      ELSE --如果无错误,提交事务

      BEGIN

      COMMIT TRANSACTION

      END

      GO

      十八、索引

      1、索引类型

      唯一索引:唯一索引不允许两行具有相同的索引值

      主键索引:为表定义一个主键将自动创建主键索引,主键索引是唯一索引的特殊类型。

      主键索引要求主键中的每个值是唯一的,并且不能为空

      聚集索引(Clustered):表中各行的物理顺序与键值的逻辑(索引)顺序相同,每个表只

      能有一个

      非聚集索引(Non-clustered):非聚集索引指定表的逻辑顺序。数据存储在一个位置,索

      引存储在另一个位置,索引中包含指向数据存储位置的指针。可以有多个,小于 249 个

      2、使用 T-SQL 语句创建索引

      CREATE [UNIQUE] [CLUSTERED|NONCLUSTERED] INDEX index_name

      ON table_name (column_name…)

      [WITH FILLFACTOR=x]

      UNIQUE 表示唯一索引,可选。

      CLUSTERED、NONCLUSTERED 表示聚集索引还是非聚集索引,可选。

      FILLFACTOR 表示填充因子,指定一个 0 到 100 之间的值,该值指示索引页填满的空间所

      占的百分比。

      3、索引的优缺点

      (1)优点

      A、加快访问速度

      B、加强行的唯一性

      (2)缺点

      A、带索引的表在数据库中需要更多的存储空间

      B、操纵数据的命令需要更长的处理时间,因为它们需要对索引进行更新

      4、创建索引的指导原则

      (1)请按照下列标准选择建立索引的列

      A、该列用于频繁搜索

      B、该列用于对数据进行排序

      (2)请不要使用下面的列创建索引

      A、列中仅包含几个不同的值。

      B、表中仅包含几行。为小型表创建索引可能不太划算,因为 SQL Server 在索引中搜索

      数据所花的时间比在表中逐行搜索所花的时间更长

      5、索引例句

      USE stuDB

      GO

      IF EXISTS (SELECT name FROM sysindexes WHERE name = 'IX_writtenExam')

      DROP INDEX stuMarks.IX_writtenExam

      /*--笔试列创建非聚集索引:填充因子为 30%--*/

      CREATE NONCLUSTERED INDEX IX_writtenExam

      ON stuMarks(writtenExam)

      WITH FILLFACTOR= 30

      GO

      /*-----指定按索引 IX_writtenExam 查询----*/

      SELECT * FROM stuMarks (INDEX=IX_writtenExam)

      WHERE writtenExam BETWEEN 60 AND 90

      十九、视图

      1、是么是视图

      A、视图是一张虚拟表,它表示一张表的部分数据或多张表的综合数据,其结构和数据

      是建立在对表的查询基础上

      B、视图中并不存放数据,而是存放在视图所引用的原始表(基表)中

      C、同一张原始表,根据不同用户的不同需求,可以创建不同的视图

      2、视图的用途

      A、筛选表中的行

      B、防止未经许可的用户访问敏感数据

      C、降低数据库的复杂程度

      D、将多个物理数据库抽象为一个逻辑数据库

      3、使用 T-SQL 语句创建视图

      CREATE VIEW view_name

      AS

      

      GO

      4、视图例句

      IF EXISTS (SELECT * FROM sysobjects WHERE name = 'view_stuInfo_stuMarks')

      DROP VIEW view_stuInfo_stuMarks

      GO

      CREATE VIEW view_stuInfo_stuMarks

      AS

      SELECT 姓名=stuName,学号=stuInfo.stuNo,

      笔试成绩 =writtenExam, 机试成绩=labExam,平均分=(writtenExam+labExam)/2

      FROM stuInfo LEFT JOIN stuMarks

      ON stuInfo.stuNo=stuMarks.stuNo

      GO

      SELECT * FROM view_stuInfo_stuMarks

      二十、存储过程

      1、什么是存储过程(procedure)

      一组预编译的 SQL 语句,它可以包含数据操纵语句、变量、逻辑控制语句等。

      2、存储过程的优点

      A、执行速度更快

      B、允许模块化程序设计

      C、提高系统安全性

      D、减少网络流通量

      3、存储过程的分类

      (1)系统存储过程

      由系统定义,存放在 master 数据库中,类似 C 语言中的系统函数,系统存储过程的名

      称都以“sp_”开头或”xp_”开头。

      (2)用户自定义存储过程

      由用户在自己的数据库中创建的存储过程,类似 C 语言中的用户自定义函数。

      4、常用的系统存储过程

      扩展存储过程:xp_cmdshell

      可以执行 DOS 命令下的一些的操作,以文本行方式返回任何输出

      调用语法:

      EXEC xp_cmdshell DOS 命令 [NO_OUTPUT]

      例句:

      EXEC xp_cmdshell 'mkdir d:\\bank', NO_OUTPUT

      EXEC xp_cmdshell 'dir D:\\bank\\' --查看文件

      系统存储过程 说明

      sp_databases 列出服务器上的所有数据库。

      sp_helpdb 报告有关指定数据库或所有数据库的信息

      sp_renamedb 更改数据库的名称

      sp_tables 返回当前环境下可查询的对象的列表

      sp_columns 回某个表列的信息

      sp_help 查看某个表的所有信息

      sp_helpconstraint 查看某个表的约束

      sp_helpindex 查看某个表的索引

      sp_stored_procedures 列出当前环境中的所有存储过程。

      sp_password 添加或修改登录帐户的密码。

      sp_helptext 显示默认值、未加密的存储过程、用户定义的存储过

      程、触发器或视图的实际文本。

      5、使用 T-SQL 语句创建和调用存储过程

      创建:

      CREATE PROC[EDURE] 存储过程名

      @参数 1 数据类型 = 默认值,

      …… ,

      @参数 n 数据类型 = 默认值

      AS

      SQL语句

      GO

      调用:

      EXEC 过程名 [参数]

      注意:

      A、和 C 语言的函数一样,参数可选

      B、参数分为输入参数、输出参数

      C、输入参数允许有默认值

      D、存储过程的大大小为 128 MB

      (1)不带参数的存储过程

      创建:

      CREATE PROCEDURE proc_stu

      AS

      DECLARE @writtenAvg float,@labAvg float

      SELECT @writtenAvg=AVG(writtenExam),

      @labAvg=AVG(labExam) FROM stuMarks

      print '笔试平均分:'+convert(varchar(5),@writtenAvg)

      print '机试平均分:'+convert(varchar(5),@labAvg)

      IF (@writtenAvg>70 AND @labAvg>70)

      print '本班考试成绩:优秀'

      ELSE

      print '本班考试成绩:较差'

      print '--------------------------------------------------'

      print ' 参加本次考试没有通过的学员:'

      SELECT stuName,stuInfo.stuNo,writtenExam,labExam

      FROM stuInfo INNER JOIN stuMarks ON stuInfo.stuNo=stuMarks.stuNo

      WHERE writtenExam<60 OR labExam<60

      GO

      调用:

      EXEC proc_stu

      (2)带输入参数的存储过程

      创建:

      CREATE PROCEDURE proc_stu

      @writtenPass int=60, --输入参数可带默认值

      @labPass int=60

      AS

      print '--------------------------------------------------'

      print ' 参加本次考试没有通过的学员:'

      SELECT stuName,stuInfo.stuNo,writtenExam,

      labExam FROM stuInfo

      INNER JOIN stuMarks ON stuInfo.stuNo=stuMarks.stuNo

      WHERE writtenExam<@writtenPass OR labExam<@labPass

      GO

      调用:

      EXEC proc_stu --都采用默认值

      EXEC proc_stu 64 --第二个参数采用默认值

      EXEC proc_stu @labPass=55 --第一个参数采用默认值

      EXEC proc_stu 60,55 --都不采用默认值

      (3)带输出参数的

      创建:

      CREATE PROCEDURE proc_stu

      @notpassSum int OUTPUT, --输出(返回)参数

      @writtenPass int=60, --推荐将默认参数放后面

      @labPass int=60

      AS

      ……

      SELECT stuName,stuInfo.stuNo,writtenExam,

      labExam FROM stuInfo INNER JOIN stuMarks

      ON stuInfo.stuNo=stuMarks.stuNo

      WHERE writtenExam<@writtenPass OR labExam<@labPass

      SELECT @notpassSum=COUNT(stuNo)

      FROM stuMarks WHERE writtenExam<@writtenPass OR labExam<@labPass

      GO

      调用:

      /*---调用存储过程----*/

      DECLARE @sum int

      EXEC proc_stu @sum OUTPUT ,64

      print '--------------------------------------------------'

      IF @sum>=3

      print '未通过人数:'+convert(varchar(5),@sum)+ '人,

      超过 60%,及格分数线还应下调'

      ELSE

      print '未通过人数:'+convert(varchar(5),@sum)+ '人,

      已控制在 60%以下,及格分数线适中'

      GO

      6、处理存储过程中的错误

      (1)PRINT 语句显示错误信息

      可以使用 PRINT 语句显示错误信息,但这些信息是临时的,只能显示给用户

      (2)RAISERROR 显示用户定义的错误信息

      可指定严重级别,设置系统变量@@ERROR,记录所发生的错误等。

      (3)RAISERROR 语句的用法

      RAISERROR (msg_id | msg_str,severity,state WITH option[,...n]])

      msg_id:在 sysmessages 系统表中指定用户定义错误信息。

      msg_str:用户定义的特定信息,长 255 个字符。

      severity:定义严重性级别。用户可使用的级别为 0–18 级。

      state:表示错误的状态,1 至 127 之间的值。

      option:指示是否将错误记录到服务器错误日志中。

      (4)例句

      CREATE PROCEDURE proc_stu

      @notpassSum int OUTPUT, --输出参数

      @writtenPass int=60, --默认参数放后

      @labPass int=60 --默认参数放后

      AS

      IF (NOT @writtenPass BETWEEN 0 AND 100)

      OR (NOT @labPass BETWEEN 0 AND 100)

      BEGIN

      RAISERROR (‘及格线错误,请指定 0-100 之间的分 数,统计中断退出',16,1)

      RETURN ---立即返回,退出存储过程

      END

      …..其他语句同上例,略

      GO

      /*---调用存储过程,测试 RAISERROR 语句----*/

      DECLARE @sum int, @t int

      EXEC proc_stu @sum OUTPUT ,604

      SET @t=@@ERROR

      print '错误号:'+convert(varchar(5),@t )

      IF @t<>0

      RETURN --退出批处理,后续语句不再执行

      print '--------------------------------------------------'

      IF @sum>=3

      print '未通过人数:'+convert(varchar(5),@sum)+ '人,超过 60%,及格分数线还应下调'

      ELSE

      print '未通过人数:'+convert(varchar(5),@sum)+ '人,已控制在 60%以下,

      及格分数线适中'

      GO

      二十一、触发器

      1、创建触发器的语法

      CREATE TRIGGER trigger_name ON table_name

      [WITH ENCRYPTION]

      FOR [DELETE, INSERT, UPDATE]

      AS

      T-SQL 语句……

      GO

      2、例句

      (1)Insert 触发器

      CREATE TRIGGER trig_transInfo ON transInfo

      FOR INSERT

      AS

      DECLARE @type char(4),@outMoney MONEY

      DECLARE @myCardID char(10),@balance MONEY

      SELECT @type=transType,@outMoney=transMoney,

      @myCardID=cardID FROM inserted

      IF (@type='支取')

      UPDATE bank SET currentMoney=currentMoney-@outMoney

      WHERE cardID=@myCardID

      ELSE

      UPDATE bank SET currentMoney=currentMoney+@outMoney

      WHERE cardID=@myCardID

      GO

      (2)Delete 触发器

      CREATE TRIGGER trig_delete_transInfo ON transInfo

      FOR DELETE

      AS

      print '开始备份数据,请稍后......'

      IF NOT EXISTS(SELECT * FROM sysobjects WHERE name='backupTable')

      SELECT * INTO backupTable FROM deleted

      ELSE

      INSERT INTO backupTable SELECT * FROM deleted

      print '备份数据成功,备份表中的数据为:'

      SELECT * FROM backupTable

      GO

      (3)Update 触发器

      CREATE TRIGGER trig_update_bank ON bank

      FOR UPDATE

      AS

      DECLARE @beforeMoney MONEY,@afterMoney MONEY

      SELECT @beforeMoney=currentMoney FROM deleted

      SELECT @afterMoney=currentMoney FROM inserted

      IF ABS(@afterMoney-@beforeMoney)>20000

      BEGIN

      print '交易金额:'+convert(varchar(8),

      ABS(@afterMoney-@beforeMoney))

      RAISERROR ('每笔交易不能超过 2 万元,交易失败',16,1)

      ROLLBACK TRANSACTION

      END

      GO

      CREATE TRIGGER trig_update_transInfo ON transInfo

      FOR UPDATE

      AS

      IF UPDATE(transDate) --判断是否被更改

      BEGIN

      print '交易失败.....'

      RAISERROR (‘安全警告:交易日期不能修改,由系统自动产生',16,1)

      ROLLBACK TRANSACTION

      END

      GO

          更多相关内容,请关注课课家提供的资料!

课课家教育

未登录

1