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 数据库,则删除
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
<select语句……>
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
SQL Server 编程入门的更多相关文章
- SQL Server编程入门
SQL编程要比Java编程.C#编程简单许多,下面我们直接讲干货21:04:31 使用变量 局部变量 在T-SQL中,局部变量的名称必须以标记@作为前缀.T-SQL的局部变量其实和Java中的局部变量 ...
- SQL Server 编程入门经典(3)之T-SQL基本语句
本章内容简介: 如何从数据库检索数据(SELECT) 如何向表中插入数据(INSERT) 如何适当更新数据(UPDATE) 如何删除表中数据(DELETE) 3.1 基本SELECT语句 如果你在此 ...
- Oracle与SQL SERVER编程差异分析(入门)
网上有关Oracle与SQL SERVER性能差异的文章很多,结论往往是让你根据数据量与预算来选择数据库.但实际项目中,特别是使用 .Net 开发的系统,支持以上两种数据库或者更多已经成为Boss的普 ...
- c#Winform程序调用app.config文件配置数据库连接字符串 SQL Server文章目录 浅谈SQL Server中统计对于查询的影响 有关索引的DMV SQL Server中的执行引擎入门 【译】表变量和临时表的比较 对于表列数据类型选择的一点思考 SQL Server复制入门(一)----复制简介 操作系统中的进程与线程
c#Winform程序调用app.config文件配置数据库连接字符串 你新建winform项目的时候,会有一个app.config的配置文件,写在里面的<connectionStrings n ...
- SQL Server复制入门(一)----复制简介【转】
SQL Server复制入门(一)----复制简介 简介 SQL Server中的复制(Replication)是SQL Server高可用性的核心功能之一,在我看来,复制指的并不仅仅是一项技术,而是 ...
- SQL Server编程系列(2):SMO常用对象的有关操作
原文:SQL Server编程系列(2):SMO常用对象的有关操作 在上一篇周公简单讲述了SMO的一些基本概念,实际上SMO体系结构远不止周公在上一篇中讲述的那么简单,下图是MSDN上给出的一个完整的 ...
- SQL Server编程系列(1):SMO介绍
原文:SQL Server编程系列(1):SMO介绍 续篇:SQL Server编程系列(2):SMO常用对象的有关操作 最近在项目中用到了有关SQL Server管理任务方面的编程实现,有了一些自己 ...
- 《SQL Server从入门到精通》
书名 <SQL Server从入门到精通> 图片 时间 2017-6月 学习 书还可以看完不痛不痒 光盘里面是c的视频有趣这是要我学c的节奏啊,可以写一些基础sql语句也是一门语言叫T-s ...
- (转) SQL Server编程系列(1):SMO介绍
最近在项目中用到了有关SQL Server管理任务方面的编程实现,有了一些自己的心得体会,想在此跟大家分享一下,在工作中用到了SMO/SQL CLR/SSIS等方面的知识,在国内这方面的文章并不多见, ...
随机推荐
- Qt 调用 Java 方法笔记
Qt 调用 Java 方法笔记 假设遇到相似的错误: error: undefined reference to '_jstring* QAndroidJniObject::callStaticMet ...
- phpqrcode生成带logo的二维码图片及带文字的二维码图片
<?php require_once "./phpqrcode/phpqrcode.php"; /** * 这样就可以生成二维码了,实际上在png这个方法里还有几个参数需要使 ...
- 在VC6.0中多线程编程演示样例(带同步信号量)
直接上代码: #include <windows.h>//必要的头文件,使用Windows API函数 #include <stdio.h> int index = 0; in ...
- 加密壳之ACProtect之OEP的处理
菜驹也玩加密壳之ACProtect之OEP的处理 附件下载:加壳文件和pdf 1. 加密过程: ACProctect v1.41版本号 分析对OEP入口点代码的偷取 2. 分析过程 ...
- SpringMVC_架构 --跟海涛学SpringMVC(学习笔记)
重点: 1.工作流程及实现原理 2.配置及使用方法 3.共同函数 前言 1.2.模型: 1.2.1.此处模型使用JavaBean,可能造成JavaBean组件类很庞大,一般现在项目都是采用三层架构,而 ...
- struts2 Action获取表单数据
1.通过属性驱动式 1.首先设置 表单中的数据的name值 如:<input type="text" name="username" value=&quo ...
- 滑动窗体的最大值(STL的应用+剑指offer)
滑动窗体的最大值 參与人数:767时间限制:1秒空间限制:32768K 通过比例:21.61% 最佳记录:0 ms|8552K(来自 ) 题目描写叙述 给定一个数组和滑动窗体的大小.找出全部滑动窗体里 ...
- Oracle 表的创建 及相关參数
1. 创建表完整语法 CREATE TABLE [schema.]table (column datatype [, column datatype] - ) [TABLESPACE tablespa ...
- YTU 2838: 改错题AB-装置连接
2838: 改错题AB-装置连接 时间限制: 1 Sec 内存限制: 128 MB 提交: 81 解决: 49 题目描述 注:本题只需要提交标记为修改部分之间的代码,请按照C++方式提交. 有AB ...
- BZOJ3224:普通平衡树(splay练习)
您需要写一种数据结构(可参考题目标题),来维护一些数,其中需要提供以下操作:1. 插入x数2. 删除x数(若有多个相同的数,因只删除一个)3. 查询x数的排名(若有多个相同的数,因输出最小的排名)4. ...