sql语句(SQL SERVER)
1、第一节
1.1什么是数据库
用来存储数据的仓库 ,就像存放文件的保险柜。
1.2如何创建数据库
拿SQL server举例
两种方式:
1) 右键数据库-》创建数据库
2)SQL 语句创建
新建查询链接-》输入以下语句-》选中执行
--CREATE DATABASE [数据库名]
--例:创建学校数据库
CREATE DATABASE SCHOOL;
1.3如何创建表
1)选择数据库-》右键创建表
设置主键-》右键设计-》右键所选对象(例如:id)-》设置主键
2)语句创建,新建查询-》输入语句
CREATE TABLE [表名]
([字段] int PRIMARY KEY,--设置主键[字段] varchar(20) NOT NULL,--不为空[字段] int ,[字段] int DEFAULT [默认值],--设置默认值
);CREATE TABLE Student
(id int PRIMARY KEY,name varchar(20) NOT NULL,age int ,sex int DEFAULT 1,phone int
);
2、第二节(查询)
2.1检索(SELECT)
查找单列数据
SELECT name
FROM Student;
查找多列数据
SELECT id,name,sex
FROM Student;
查找全部数据
SELECT *
FROM Student
2.2检索数据排序
默认排序是根据数据插入顺序输出
排序 ORDER BY(默认升序)
ASC升序
DESC降序
单个列排序
--根据id升序排序
SELECT name
FROM Student
ORDER BY id;
多个列排序
根据需求进行排序
SELECT id,name,age
FROM Student
ORDER BY name,age;
按列位置进行排序
根据第二列第三列排序(输出结果同上)
SELECT id,name,age
FROM Student
ORDER BY 2,3;
指定方向排序
--根据id降序排列
SELECT name
FROM Student
ORDER BY id DESC;--根据id升序排列
SELECT name
FROM Student
ORDER BY id ASC;
2.3过滤查询
使用WHERE语句查询
--查找姓名为张三的信息
SELECT name,age,sex
FROM Student
WHERE name = '张三';
操作符
检查单个值
--查找年龄大于等于18的信息
SELECT name,age,sex
FROM Student
WHERE age>=18;
不匹配查询
--查找性别不是男(1)的信息【查找所有女生(0)】
SELECT name,age,sex
FROM Student
WHERE sex!=1;
范围值查询
--查找年龄在6-18的信息
SELECT name,age,sex
FROM Student
WHERE age BETWEEN 6 AND 18;
空值查询
--查找手机号为空的信息
SELECT name,age,sex
FROM Student
WHERE phone IS NULL;
2.4高级过滤查询
1、组合查询
AND
--查找年龄大于十八的男生
SELECT name,age,sex
FROM Student
WHERE age >18 AND sex = 1;
OR
--查找年龄大于十八或者是男生的信息
SELECT name,age,sex
FROM Student
WHERE age >18 OR sex = 1;
计算次序
AND 、OR进行组合
--年龄大于18的id大于等于1或者是男生的信息
SELECT name,age,sex
FROM Student
WHERE (id>=1 OR sex = 1)
AND age >18
2、IN操作符
用来指定范围
--查找年龄在6-18的信息并根据age升序排序
SELECT name,age,sex
FROM Student
WHERE age IN (6,18)
ORDER BY age;
3、NOT操作符
--查找女生并按年龄升序排序
SELECT name,age,sex
FROM Student
WHERE NOT sex=1
ORDER BY age;
2.5通配符进行过滤查询
1、LIKE操作符
通配符:用来匹配值的一部分的特殊字符
搜索模式:有字面值、通配符或两者进行组合构成的搜索条件
1.1百分号(%)通配符
%表示任意字符出现的任意次数
--查找姓氏为李的所有信息
SELECT *
FROM Student
WHERE name LIKE '李%';
1.2下划线(_)通配符
_ 通配符匹配任意单个字符
--查找姓氏为李姓名为两位的所有信息
SELECT *
FROM Student
WHERE name LIKE '李_';
1.3方括号([ ])通配符
[]通配符用来指定一个字符集,必须匹配指定的位置
--查找姓氏为李和王的所有信息
SELECT *
FROM Student
WHERE name LIKE '[李王]%';
^ 脱字节
用来否定条件
--查找姓氏不为李和王的所有信息
SELECT *
FROM Student
WHERE name LIKE '[^李王]%';
3、第三节(计算字段)
3.1计算字段
例如查找公司名称、同时显示公司名称和公司地址,但是这两个信息存放在两列中,我们需要的字段表中并没有直接显示,因此我们需要直接从数据库中检索出转换、计算或格式化过的数据,这样的数据被称为计算字段
3.2拼接字段
将两个值进行拼接成单个值
--查找姓名年龄 并将其拼接成一列
SELECT name + '('+age+')'
FROM Student
格式化数据时可使用函数(例:去除串尾空格,使用函数 RTRIM() )
--查找姓名年龄 并将其拼接成一列
SELECT RTRIM(name) + '('+RTRIM(age)+')'
FROM Student
使用别名
--查找姓名年龄 并将其拼接成一列
SELECT RTRIM(name) + '('+RTRIM(age)+')' AS NAME
FROM Student
3.3执行算术计算
--查找信息并添加sum列(男生年龄+1,女生年龄+0)
SELECT name,age,sex,age+sex AS SUM
FROM Student
4、第四节(函数)
4.1文本处理函数
UPPER()函数 文本转大写
--查找姓名并转大写
SELECT UPPER(name)
FROM STUDENT
用法同上
SOUNDEX()函数
soundex是一个将任何文本串转换为描述其语音表示的字母数字模式的算法。soundex考虑了类似的发音字符和音节,使得对字符串进行发音比较而不是字母比较。
例如由于输入错误name列中有sam,但是实际是san,直接查找会显示为空,使用SOUNDEX()则可以避免这样的情况
SELECT *
FROM STUDENT
WHERE SOUNDEX(name) = SOUNDEX('san');
4.2日期和时间处理函数
--查找入学时间是2022的学生姓名
SELECT name
FROM STUDENT
WHERE DATEPART(yyyy,date) = 2022;
DATEPART(datapart,date)
date 参数是合法的日期表达式。datepart 参数可以是下列的值:
datepart | 缩写 |
---|---|
年 | yy, yyyy |
季度 | qq, q |
月 | mm, m |
年中的日 | dy, y |
日 | dd, d |
周 | wk, ww |
星期 | dw, w |
小时 | hh |
分钟 | mi, n |
秒 | ss, s |
毫秒 | ms |
微妙 | mcs |
纳秒 | ns |
4.3数值处理函数
5、第五节(聚集函数)
5.1 sql中的聚集函数
5.2 AVG()函数
平均值
--查找平均年龄
SELECT AVG(age) AS AVGAGE
FROM STUDENT;
--查找男生的平均年龄
SELECT AVG(age) AS AVGAGE
FROM STUDENT
WHERE sex = 1;
5.3 COUNT()函数
计算个数
--查找人数
SELECT COUNT(name) AS COU
FROM STUDENT;
--查找男生人数
SELECT COUNT(name) AS COU
FROM STUDENT
WHERE sex = 1;
5.4 MAX() \ MIN()函数
MAX()最大值
--查找最大年龄
SELECT MAX(age) AS AGE
FROM STUDENT;
MIN()最小值
--查找最小年龄
SELECT MIN(age) AS AGE
FROM STUDENT;
5.5 SUM()函数
求和
--查找年龄和
SELECT SUM(age) AS AGESUM
FROM STUDENT;
5.6 聚集不同值
ALL DISTINCT
默认是ALL 全部数据
DISTINCT 对查询结果去重
--查找不同年龄段的个数
SELECT COUNT(DISTINCT age) AS COUN
FROM STUDENT;
5.7 组合聚集函数
--数据个数、最大年龄、最小年龄、平均年龄
SELECT COUNT(*) AS NUM,MAX(AGE) AS MAX,MIN(AGE) AS MIN,AVG(AGE) AS AVG
FROM STUDENT;
6、第六节(分组)
GROUP BY
6.1 创建分组
--根据姓名分组
SELECT NAME , COUNT(*) AS NUM
FROM STUDENT
GROUP BY NAME;
6.2 过滤分组
通过HAVING 进行过滤分组
HAVING 支持 WHERE 所有的通配符
--根据姓名分组并过滤出出现次数大于等于二的姓名和出现次数
SELECT NAME , COUNT(*) AS NUM
FROM STUDENT
GROUP BY NAME
HAVING COUNT(*)>=2;
6.3 分组和排序
--分组并根据NAME排序
SELECT NAME , COUNT(*) AS NUM
FROM STUDENT
GROUP BY NAME
HAVING COUNT(*)>=2
ORDER BY ID,AGE;
7、第七节(子查询)
7.1 利用子查询进行过滤
--查找成绩大于等于90分的学生
SELECT NAME
FROM STUDENT
WHERE ID IN ( SELECT studentidFROM GradeWHERE SCORE >=90);
也可嵌套多个子查询,但在实际开发中考虑性能,并不会使用过多的嵌套
7.2作为计算字段使用子查询
--查找学生姓名、年龄、总成绩
SELECT NAME, AGE,(SELECT SUM(SCORE)FROM GRADEWHERE grade.studentid = student.id) AS SCORE
FROM STUDENT;
8、第八节(表联结)
8.1创建联结
两个表连接
--查找姓名 年龄 成绩
SELECT NAME,AGE,SCORE
FROM STUDENT,GRADE
WHERE STUDENT.ID = GRADE.STUDENTID;
8.2笛卡尔积
检索出的行的数目 = 第一个表行数*第二个表的行数
SELECT NAME,AGE,SCORE
FROM STUDENT,GRADE
WHERE STUDENT.ID = GRADE.STUDENTID;
表1
id | name | age |
---|---|---|
1 | 张三 | 18 |
2 | 李四 | 19 |
表2
id | studentid | subjectid | score |
---|---|---|---|
1 | 1 | 1 | 88 |
2 | 1 | 2 | 69 |
3 | 2 | 1 | 59 |
4 | 2 | 2 | 80 |
检索结果
name | age | score |
---|---|---|
张三 | 18 | 88 |
张三 | 18 | 69 |
李四 | 19 | 59 |
李四 | 19 | 80 |
8.3内连接
INNER JOIN
内连接只匹配两者的公共部分
--查找两个学生表中重复的学生
SELECT *
FROM STUDENT_1 A
INNER JOIN STUDENT_2 B
ON A.ID = B.ID;
8.4自联结
--例:想要给张老师所带班级的所有代课老师授予优秀教师,我们需要先找到张老师所带的班级,然后找到该班级的代课老师SELECT TEA_ID,TEA_NAME,TEA_PHONE
FROM TEACHERS
WHERE CLASS_ID = (SELECT CLASS_IDFROM TEACHERSWHERE TEA_NAME = '张老师');
8.5外连接
左连接
LEFT JOIN \ LEFT OUTER JOIN(两者没有区别,前者是后者简写)
以左边信息为主,只查询左表有的信息。
--所有学生包含没有考试的学生
SELECT *
FROM STUDENT A
LEFT JOIN GRADE B
ON A.ID = B.STUDENTID;
右联结
RIGHT JOIN\RIGHT OUTER JOIN
只匹配右表存在的信息
--查询参加考试的学生的信息
SELECT *
FROM STUDENT A
RIGHT JOIN GRADE B
ON A.ID = B.STUDENTID;
全联结
FULL JOIN \ FULL OUTER JOIN
--查找所有信息
SELECT *
FROM STUDENT A
FULL JOIN GRADE B
ON A.ID = B.STUDENTID;
8.6使用带有聚集函数的联结
--查找参加考试信息并统计人数
SELECT NAME ,COUNT(NAME) AS NUM
FROM STUDENT A
RIGHT JOIN GRADE B
ON A.ID = B.STUDENTID
GROUP BY A.NAME;
8.7组合查询
使用UNION
-- 查询 年龄大于18的男生
SELECT ID,NAME,AGE
FROM STUDENT
WHERE AGE>18
UNION
SELECT ID,NAME,AGE
FROM STUDENT
WHERE SEX = 1;
UNION会自动去除重复的行
若要想要包含重复的行则使用UNION ALL
-- 查询 年龄大于18的男生
SELECT ID,NAME,AGE
FROM STUDENT
WHERE AGE>18
UNION ALL
SELECT ID,NAME,AGE
FROM STUDENT
WHERE SEX = 1;
对组合查询进行排序
-- 查询 年龄大于18的男生,并根据id,NAME,AGE排序
SELECT ID,NAME,AGE
FROM STUDENT
WHERE AGE>18
UNION
SELECT ID,NAME,AGE
FROM STUDENT
WHERE SEX = 1
GROUP BY ID,NAME,AGE;
9、第九节(插入)
9.1数据插入(INSERT)
1、插入完整行
--插入整行信息
INSERT INTO STUDENT
VALUES ('6','JACK','23','1','1234567');
-- 或
-- 这样更加安全,但相对繁琐
INSERT INTO STUDENT(ID,NAME,AGE,SEX,PHONE
)
VALUES ('6','JACK','23','1','1234567');
2、插入部分行
-- 插入id,姓名,年龄
INSERT INTO STUDENT(ID,NAME,AGE
)
VALUES ('6','JACK','23');
3、插入检索出的数据
-- 查找STUDENT插入到STUDENT_S中
INSERT INTO STUDENT_S(ID,NAME,AGE,SEX,PHONE)
SELECT ID,NAME,AGE,SEX,PHONE
FORM STUDENT;
9.2 从一个表复制到另一个表
SELECT *
INTO STUDENT_S
FROM Student;
10、更新和删除数据
10.1 更新数据
UPDATE
--修改姓名,年龄
UPDATE STUDENT
SET NAME = 'MC赵四',AGE = '55'
WHERE ID = '5';
10.2 删除数据
DELETE
--从表中删除一行数据
DELETE FROM STUDENT
WHERE ID = '8';
ALTER
--删除列
ALTER TABLE TEACHER
DROP COLUMN TEACHERID;
11、创建和操作表
11.1 创建表基础
CREATE TABLE STUDENTS
(S_ID INT PRIMARY KEY, --主键(唯一标识)NAME VARCHAR(20) NOT NULL, --(不为空)AGE INT NULL, --为空(可省略,默认不填为空)SEX VARCAHR(10) DEFAULT '男' --设置默认值
)
11.2约束
主键 PRIMARY KEY
主键是一种特殊的约束,用来保证一个列中的值时唯一的,并且永远不改动。
-- 创建表时声明自增主键
CREATE TABLE TTT
(ID INT NOT NULL PRIMARY KEY IDENTITY(1001,1),-- IDENTITY(初始值,自增量)NAME VARCHAR(20) NOT NULL,AGE INT,SEX VARCHAR(10)
)
-- 修改主键
ALTER TABLE TTT
ADD PRIMARY KEY (ID);
外键 FOREIGN KEY
外键时表中的一个列,必须与另一个表的主键对应。通常用于连接两个表
-- 创建表时声明外键
CREATE TABLE TTT
(ID INT NOT NULL PRIMARY KEY IDENTITY(1001,1),-- IDENTITY(初始值,自增量)NAME VARCHAR(20) NOT NULL,AGE INT CHECK(AGE>=0 AND AGE<200),SEX VARCHAR(10) DEFAULT '男',PHONE INT NOT NULL UNIQUE,CLASSID INT REFERENCES CLASS(ID)
);
-- 修改外键
ALTER TABLE TTT
ADD CLASSID INT
FOREIGN KEY(CLASSID) REFERENCES CLASS(ID);
非空 NOT NULL
使数据不能为空
NAME VARCHAR(20) NOT NULL;
默认 DEFAULT
给数据设置默认值
SEX VARCHAR(10) DEFAULT '男';
检查 CHECK
检查约束用来保证这一列数据满足一组指定的条件。
-- 年龄满足大于等于0小于200
AGE INT CHECK(AGE>=0 AND AGE<200)
唯一 UNIQUE
约束一组数据中该列数据没有重复、唯一。
-- 手机号唯一
PHONE INT NOT NULL UNIQUE,
11.3 更新表
ALERT
添加时可以添加约束
--添加列
ALTER TABLE STUDENT
ADD CLASSID INT ;
--添加列并设成外键
ALTER TABLE STUDENT
ADD CLASSID INT
FOREIGN KEY(CLASSID) REFERENCES CLASS(ID);
--删除列
ALTER TABLE TEACHER
DROP COLUMN TEACHERID;
--添加约束--
--添加外键
ALTER TABLE STUDENT
ADD CONSTRAINT CLASSID
FOREIGN KEY(CLASSID) REFERENCES CLASS(ID);
--添加主键
ALTER TABLE STUDENT
ADD CONSTRAINT ID
PRIMARY KEY(ID);
--添加默认约束
ALTER TABLE STUDENT
ADD CONSTRAINT AGE
DEFAULT 1 FOR AGE;
11.4 删除表
DROP
DROP TABLE STUDENT
11.5 重命名表
SP_RENAME 'STUDENT_S','STUDENT_S1';
12、第十二节(视图)
12.1 什么是视图
视图是一个虚拟的表,并不存在具体的列和行。本质上就是查询。
例,我们想要查找某一学科及格的同学。
--查找某一学科及格的同学
SELECT STUDENT.NAME,STUDENT.LASSID
FROM STUDENT,GRADE,SUBJECT
WHERE STUDENT.ID = GRADE.STUDENTIDAND GRADE.SUBJECTID = SUBJECT.IDAND SUBJECT.NAME = '语文'AND GRADE.SCORE >= 60;
任何需要这个数据的人都必须要了解相关表的结构,并知道如何创建查询和对表进行联结。
为了检索别的学科及格的学生数据,必须要修改where语句,因此非常麻烦。
如果我们把这个查询封装成一个名为 sub_pass的虚拟表。这样就可一比较简单的实现不同科目的查询。
--SUB_PASS表
SELECT STUDENT.NAME,STUDENT.CLASSID,SUBJECT.name as subna
FROM STUDENT,GRADE,SUBJECT
WHERE STUDENT.ID = GRADE.STUDENTIDAND GRADE.SUBJECTID = SUBJECT.IDAND GRADE.SCORE >= 60;
例:
--查询数学
SELECT NAME,CLASSID
FROM SUB_PASS
WHERE subna = '数学';
12.2 为什么使用视图
- 重用SQL语句
- 简化复杂sql操作,在编写查询后,可以方便的重用它而不必知道他的基本结构
- 使用表的组成部分而不是整个表
- 保护数据,可以给用户授予表的特定部分的访问权限而不是整个表的访问权限
- 能够更改数据的格式和表示,视图可以返回和底层表的表示很格式不同的数据。
12.3 视图的规则和限制
视图必须唯一命名(与表一样)
对视图的创建数目没有限制
为了创建视图,必须具有足够的访问权限,通常由数据库管理人员授权
视图可以嵌套
视图不能使用索引
12.4 创建视图
CREATE VIEW 创建视图
DROP VIEW 删除视图
--创建sub_pass视图
CREATE VIEW sub_pass AS
SELECT STUDENT.NAME,STUDENT.CLASSID,SUBJECT.name as subna
FROM STUDENT,GRADE,SUBJECT
WHERE STUDENT.ID = GRADE.STUDENTIDAND GRADE.SUBJECTID = SUBJECT.IDAND GRADE.SCORE >= 60;
--查询
SELECT NAME
FROM SUB_PASS
WHERE SUBNA = '数学';
用视图重新格式化数据
-- 查看学生姓名及班级
SELECT RTRIM(NAME)+'是'+RTRIM(CLASSID)+'班' AS CLASS
FROM student;
使用视图格式化数据
-- 创建视图
CREATE VIEW STUCLASS AS
SELECT RTRIM(NAME)+'是'+RTRIM(CLASSID)+'班' AS CLASS
FROM STUDENT;
--使用视图查询
SELECT CLASS
FROM STUCLASS;
使用试图过滤掉不想要的数据
-- 过滤掉未填写班级的学生
CREATE VIEW STUCLASS AS
SELECT RTRIM(NAME)+'是'+RTRIM(CLASSID)+'班' AS CLASS
FROM STUDENT
WHERE CALSSID IS NOT NULL;
使用计算字段
-- 使用计算字段查询学生信息及教材费
CREATE VIEW BOOK_S AS
SELECT ID,NAME,BOOK_NUM,BOOK_PRICE,BOOK_NUM*BOOK_PRICE AS PRICE
FROM BOOK;
13、第十三节(存储过程)
13.1 什么是存储过程
存储过程是大型数据库系统中,一组为了完成特定功能的sql 语句集,存储在数据库中,经过一次编译后再次调用后不需要再次编译,用户通过指定存储过程并给出参数 (如果该存储过程有参数) 来调用存储过程
人话:专门干一件事的sql语句
可以由数据库调用,也可由程序调用
13.2 为什么使用存储过程
效率高
- 编译一次后会存放到数据库,每次调用时直接执行。普通sql语句保存时,会保存到其他地方,需要先分析编译在执行
降低网络流量
- 在远程调用时,不会传输大量的字符串类型sql语句
复用性
- 存储过程往往只针对一个特定的功能编写,需要某个功能时,可以再次调用
可维护性高
- 当功能需求发生小变动时,修改存储过程比较容易,花费精力小
安全性高
- 某个特定功能的存储过程一般只有特定的用户可以使用,有身份限制,相对安全性高
13.3 创建存储过程
-- 创建无参
-- 查询学生全部信息
CREATE PROCEDURE stuInfo
AS
SELECT *
FROM STUDENT;--调用,执行存储过程
EXEC stuInfo;
-- 创建有参
-- 根据传参(学生ID)来查询学生信息
CREATE PROCEDURE stuInfo(@STUID INT)
AS
SELECT *
FROM STUDENT
WHERE ID = @STUID;--调用,执行存储过程
-- 查找1号学生全部信息
EXEC stuInfo 1;
13.4 修改、删除、重命名操作
修改
-- 修改为只查找学生姓名
ALTER PROCEDURE stuInfo
AS
SELECT NAME
FROM STUDENT;
删除
DROP PROCEDURE stuInfo;
重命名
SP_RENAME stu_only, stuInfo;
13.5 有参存储过程
-- 一个参数 -----------------------
CREATE PROCEDURE stuInfo(@STUID INT)
AS
SELECT *
FROM STUDENT
WHERE ID = @STUID;-- 两个参数 -----------------------
CREATE PROCEDURE stuInfo(@STUID INT,@STUAGE INT)
AS
SELECT *
FROM STUDENT
WHERE ID = @STUID
AND AGE = @STUAGE;
--调用
EXEC stuInfo 1,11;-- 创建有返回值的存储过程 ------------
CREATE PROCEDURE stuName(@STUID INT,@s_NAME varCHAR(20) OUTPUT) AS
SELECT @s_NAME = NAME
FROM STUDENT
WHERE ID = @STUID;
-- 调用,执行存储过程,根据学号输出姓名
DECLARE @NAME VARCHAR(20)
EXEC STUNAME 1,@NAME OUTPUT
PRINT @NAME;-- 创建带通配符的存储过程 ------------
CREATE PROC STU_NAME(@S_NAME VARCHAR(20) = '%')
AS
SELECT *
FROM STUDENT
WHERE NAME LIKE @S_NAME;
-- 调用
EXEC STU_NAME '张%';
-- 或 EXEC STU_NAME '%三';-- 创建加密存储过程 -----------------
CREATE PROC STU_INFO
WITH ENCRYPTION -- WITH ENCRYPTION子句对用户隐藏存储过程的文本
AS
SELECT *
FROM STUDENT;
-- 调用
EXEC STU_INFO;
EXEC SP_HELPTEXT 'STU_INFO'; -- 对象 'STU_INFO' 的文本已加密。-- 不缓存存储过程 ------------------
CREATE PROC INFO_S
WITH RECOMPILE
ASSELECT * FROM STUDENT
GO EXEC INFO_S;EXEC SP_HELPTEXT INFO_S;-- 创建带有游标的存储过程 -----------
CREATE PROC STU_USER@S_CUR CURSOR VARYING OUTPUT
ASSET @S_CUR = CURSOR FORWORD ONLY STATIC FORSELECT ID,NAME,AGEFROM STUDENTOPEN @S_NAME;
GO
DECLARE @CUR CURSOR,@S_ID INT,@S_NAME VARCHAR(20),@S-AGE INT
EXEC STU_USER @S_CUR = @CUR OUTPUT;
FETCH NEXT FROM @CUR INTO @S_ID,@S_NAME,@S-AGE;
WHILE(@@FETCH_STATUS=0)
BEGINFETCH NEXT FROM @CUR INTO @S_ID,@S_NAME,@S-AGE;PRINT 'S_ID:'+CONVERT(VARCHAR,@S_ID)+',S_NAME:'+@S_NAME+',S_AGE'+@S_AGE;
END
CLOSE @CUR; --关闭游标
DEALLOCATE @CUR; --释放游标
创建插入数据的存储过程
CREATE PROC S_INSERT@S_ID INT ,@S_NAME VARCHAR(20)
AS
DECLARE @S_NUM INT
SELECT @S_ID = COUNT(*)+1
FROM STUDENT
SELECT @S_NUM = MAX(AGE)+1
FROM STUDENT
INSERT INTO STUDENT(ID,AGE,NAME)
VALUES(@S_ID,@S_NUM,@S_NAME);
go
exec S_INSERT 2,'魏老板';
SELECT * FROM STUDENT;
14、第十四节(事务)
14.1 事务处理
什么是事务
事务处理可以用来维护数据库的完整性,他保证成批的SQL操作要么完全执行,要么完全不执行。
事务的四大特性
原子性
- 要么全部完成,要么全部取消。如果事务崩溃,状态回到事务之前(事务回滚)
隔离性
- 隔离性是当多个用户并发访问数据库时,比如操作同一张表,数据库为每一位用户开启的用户,不能被其他事务干扰,多个并发事务之间相互隔离
- 例:T1和T2两个并发事务,在T1看来,T2发生在T1之后或之前,并不是同时进行。在T2看来是在T1之前或之后。
持久性
- 事务发生后对数据的改变是永久的
一致性
- 数据与表一致,只有合法的数据才能写入数据库
事务处理
事务:指一组AQL语句
回退(回滚):指撤销指定SQL语句的过程
提交:指将未存储的SQL语句存储到数据库
保留点:指事务处理中设置的临时占位符,你可以对它发布回退
14.2 控制事务处理
BEGIN 开启一个事务
ROLLBACK 事务回滚
COMMIT 确认事务
-- STUDENT表插入一行信息
BEGIN TRANSACTION --简写TRAN
INSERT INTO STUDENT
(ID,NAME,AGE,SEX,PHONE)
VALUES(14,'脑',22,1,11122233344
)
COMMIT TRANSACTION
ROLLBACK 事务回滚
-- 插入数据,如果插入失败回滚输出1,成功输出0
BEGIN TRAN ADDINFO
DECLARE @ERROR_S INT;
SET @ERROR_S = 0;
BEGIN TRYINSERT INTO STUDENT VALUES(9,'魏老板',23,1,12112,201);INSERT INTO STUDENT VALUES(10,'马大师',23,1,12112,201);INSERT INTO STUDENT VALUES(11,'脑师傅',23,1,12112,201);
END TRY
BEGIN CATCHSET @ERROR_S = @ERROR_S+1;
END CATCH
IF(@ERROR_S>0)
BEGINROLLBACK TRAN ADDINFO;PRINT @ERROr_S;
END
ELSE
BEGINCOMMIT TRAN ADDINFO;PRINT @ERROR_S;
END
SAVE 保留点
对于简单的事务可以使用ROLLBACK、COMMIT进行整体回退提交。而复杂的事务可能需要部分提交和回退。
为了支持部分回退事务处理,必须能在事务处理块中合适的位置放置占位符。而这些占位符就是保留字。
-- 依次插入数据,第一条数据插入成功后会设置一个保留点,第二条数据插入时,如果失败则回退到保留点。往后依次。
BEGIN TRAN ADD_UI
INSERT INTO STUDENT VALUES(21,'王富贵',23,0,12121,201);
IF @@ERROR <> 0 ROLLBACK TRAN;
SAVE TRAN SUCCESS1;
INSERT INTO STUDENT VALUES(22,'那个人',23,0,12121,201);
IF @@ERROR <> 0 ROLLBACK TRAN SUCCESS1;
SAVE TRAN SUCCESS2;
INSERT INTO STUDENT VALUES(23,'那个村',23,0,12121,201);
IF @@ERROR <> 0 ROLLBACK TRAN SUCCESS2;
SAVE TRAN SUCCESS3;
INSERT INTO STUDENT VALUES(14,'那个镇',23,0,12121,201);
IF @@ERROR <> 0 ROLLBACK TRAN SUCCESS3;
COMMIT TRAN;
15、第十五节(游标)
15.1 游标
游标(cursor)是系统为用户开设的一个数据缓冲区,存放SQL语句的执行结果。每个游标区都有一个名字,用户可以用SQL语句逐一从游标中获取记录,并赋给主变量,交由主语言进一步处理。
作用
- 遍历数据行;
- 保存查询结果,方便下文调用;
15.2 创建游标
DECLARE CURSOR_NAME(游标名称)
[insensitive] [scroll] cursor
for
select [xxxx] -- 查询语句-- 创建游标
DECLARE STU_NAME CURSOR
FOR
SELECT * FROM STUDENT;
-- 打开游标
OPEN S_NAME;-- 使用FETCH访问游标数据
-- 声明参数
DECLARE @ID INT,@NAME VARCHAR(20),@AGE INT,@SEX INT,@PHONE INT,@CLASSID INT;
FETCH NEXT FROM STU_NAME INTO @ID,@NAME,@AGE,@SEX,@PHONE,@CLASSID;
-- 打印信息
PRINT cast(@ID as varchar)+@NAME+cast(@AGE as varchar)+cast(@SEX as varchar)+cast(@PHONE as varchar)+cast(@CLASSID as varchar);
-- 打印全部学生信息
WHILE @@FETCH_STATUS = 0
BEGIN
FETCH NEXT FROM STU_NAME INTO @ID,@NAME,@AGE,@SEX,@PHONE,@CLASSID;PRINT cast(@ID as varchar)+@NAME+cast(@AGE as varchar)+cast(@SEX as varchar)+cast(@PHONE as varchar)+cast(@CLASSID as varchar);
END
--关闭游标
CLOSE STU_NAME;
next
返回结果集当前行的下一行,首次提取返回第一行。
frior
返回结果集的上一行,首次提取无数据返回。
first
返回结果集第一行。
last
返回结果集最后一行。
absolute
移动到结果集的第n行。如果n为正数,从结果集的第一行(包含第一行)起移到第n行;如果n为负数,则从结果集的最后一行起移到第n行。
relative
从游标指针的当前位置移动n行。如果n为正数,则读取游标当前位置起向后的第n行数据;如果n为负数,则读取游标当前位置起向前的第n行数据。
15.3 基于游标定位UPDATE语句和定位DELETE语句
-- UPDATE
UPDATE [表名]
SET [列名]
WHERE CURRENT [游标名];
-- 修改性别
OPEN STU_NAME;
DECLARE @ID INT,@NAME VARCHAR(20),@AGE INT,@SEX INT,@PHONE INT,@CLASSID INT
FETCH NEXT FROM STU_NAME INTO @ID,@NAME,@AGE,@SEX,@PHONE,@CLASSID;
UPDATE STUDENT SET SEX = 1
WHERE CURRENT OF STU_NAME;
CLOSE STU_NAME;-- DELETE
DELETE FROM [表名]
WHERE CURRENT OF [游标名]-- 删除一个学生数据
OPEN STU_NAME;
DECLARE @ID INT,@NAME VARCHAR(20),@AGE INT,@SEX INT,@PHONE INT,@CLASSID INT
FETCH NEXT FROM STU_NAME INTO @ID,@NAME,@AGE,@SEX,@PHONE,@CLASSID;
DELETE FROM STUDENT
WHERE CURRENT OF STU_NAME
15.4 删除游标
CLOSE 关闭游标并不会释放其占用的数据结构
若想删除需要用DEALLOCATE进行删除
DEALLOCATE STU_NAME;
16、第十六节(索引、触发器)
16.1 索引
索引是用来排序数据一加快搜索和排序操作的速度。
单列索引
CREATE INDEX NAME
ON
STUDENT(NAME)
多列suoyin
CREATE INDEX NAME
ON
STUDENT(NAME,AGE)
唯一索引
CREATE UNIQUE INDEX NAME
ON
STUDENT(NAME)
隐式索引
-- 由数据库服务器在创建某些对象的时候自动生成。例如主键约束和唯一约束。
修改索引
use database_nameexec sp_rename ‘table_name.old_name’ ‘new_name’
删除索引
DROP INDEX STUDENT.NAME;
查看索引
use [数据库名]
exec sp_helpindex [表名]
16.2 触发器
触发器时特定的存储过程,在特定的数据库活动发生时自动执行。
触发器具有以下数据的访问权:
INSERT 操作的所有数据;
UPDATE操作的所有新、旧数据;
DELETE操作中删除的数据;
触发器的作用
- 保证数据一致。例:在INSERT或UPDATE中转化所有姓名大写
- 基于某个表的变动在其他表上执行活动。例:每当更新或删除一行时将审计跟踪记录写入某个日志表
- 进行额外的验证并根据需求回退数据。例:保证某个学生的额外加分不超限定,如果超出,则阻塞插入
- 计算计算列的值或更新时间戳。
创建一个触发器
-- 插入、更新数据时会把姓名修改为大写
CREATE TRIGGER NAME_UPER
ON STUDENT
FOR INSERT,UPDATE
AS
UPDATE STUDENT
SET NAME = UPPER(NAME);
sql语句(SQL SERVER)相关推荐
- php主键自增sql语句,sql语句id自增的问题
现在的情况是页面添加信息失败,我实在不知道哪出问题了 数据库创建语句: php语句: 能在客户端写入信息,但是 id 留空不行,不是已经设置了atuo_increment ,为什么id还是不能自增啊? ...
- 更新sql语句 sql注入_SQL更新语句– SQL中的更新查询
更新sql语句 sql注入 SQL Update Statement or Update Query in SQL is used to modify the column data in table ...
- SQL语句 SQL Server(代码添加约束:主键约束,外键约束,默认值约束,check约束,规则约束)
SQL语句(基于SQL Server) 约束 primary约束,unique约束,check约束 建表时 列级 create table <table name>(<column_ ...
- mysql 删除外键 sql语句_sql server ql语句删除外键和删除
sql server ql语句删除外键和删除 alter table tablename add constraint ordersrelationship foreign key mployeeid ...
- 数据库学习day_02:表格相关sql语句 / 表格数据相关sql语句 / sql中的数据类型 / 导入外部sql文件 / 去重.是否为null.and与or.in.[x,y]
1.表相关的SQL语句 操作表相关的SQL 必须先使用某个数据库 create database mydb1; show create database mydb1; use mydb1; 如果默认不 ...
- mysql-fron快速写sql语句,SQL优化系列:如何书写高质量SQL语句(一)
写SQL语句的时候我们往往关注的是SQL的执行结果,但是是否真的关注了SQL的执行效率,是否注意了SQL的写法规范? 以下的干货分享是在实际开发过程中总结的,希望对大家有所帮助! 1. limit分页 ...
- php常见sql语句,sql语句是什么
结构化查询语言(Structured Query Language)简称SQL,结构化查询语言是一种数据库查询和程序设计语言,用于存取数据以及查询.更新和管理关系数据库系统: sql语句就是对数据库进 ...
- mysql外键设置sql语句,SQL Server 2008之SQL语句外键
xin3721网络学院为广大学员,准备了丰富了教学视频.为了更好的让大学配合视频进行学习,拓展学员的知 识面,我站特整理了大量的,技术文章,供学员参考.因此本教案需配合视频教程学习, 视频教程地址为: ...
- php主键自增sql语句,sql 自动增长的主键
问:SQL Server 2005中设计表时和在SQL Server Management Studio Express中如何得到 自动 编号字段? 答:具体步骤如下: ①像Access中的 自动 编 ...
最新文章
- python关于七巧板的代码_Css打造一个简单的静态七巧板
- mybatis多对一处理两种处理方式
- jq php异步上传图片,PHP+Ajax实现图片异步上传预览
- 优化 recipe 达到快速启动 SAP Hybris Accelerator Storefront 的方法
- BitSet之为什么用long保存信息
- 西游记里学化学,请收下我的膝盖~ | 今日最佳
- P3242 [HNOI2015] 接水果(整体二分、扫描线)
- 一步步编写操作系统 53 任务状态段TSS介绍
- 解决: idea 修改 jsp 后,页面刷新无效
- 图片异步加载框架 Android-Universal-Image-Loader
- debian安装中文字体
- .NET:事务、并发、并发问题、事务隔离级别、锁等相关资料整理
- 最简单的c语言if程序,C语言简单实用的程序-if else 嵌套式的使用例子
- CRM客户关系管理系统的设计与实现
- WAMP5配置本地服务器(超级详细教程)
- 无线覆盖商场微信吸粉解决方案
- 巴西龟饲养日志----巴西龟肺炎治疗情况
- JS创建26个小写字母数组
- 分享一款多功能免费SEO工具箱-从0开始打造高流量网站
- 编译linux内核报错,/bin/sh: 1: flex: not foundscripts/Makefile.host:9: recipe for target ‘scripts/kconfig/
热门文章
- python 导出到excel ,打开excel有错误,错误的提示为:发现“***”中的部分内容问题,是否让我们尽量尝试修复?如果您信任此工作簿的源,请单击“是”。
- 算法题-双指针(最长的指定瑕疵度的元音子串(答案、解析))
- 微信小程序wepy框架+minui踩坑之路
- 微擎服务器数据迁移 ,微擎通过迁移数据方式搬家换服务器换站点换域名【图文教程】
- python3精简笔记(三)——高级特性
- cc美团_项目注册界面实现
- E900V21E_S905L3B芯片_UWE5621-wifi-线刷固件
- hand crafted feature:histogram(直方图)
- OpenDaylight是什么?
- 树莓派3强大很多--相比树莓派2