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 Student2.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 >182、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 Student3.3執行算術計算
--查找信息并添加sum列(男生年齡+1,女生年齡+0) SELECT name,age,sex,age+sex AS SUM FROM Student4、第四節(函數)
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 參數可以是下列的值:
| 年 | 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
| 1 | 張三 | 18 |
| 2 | 李四 | 19 |
表2
| 1 | 1 | 1 | 88 |
| 2 | 1 | 2 | 69 |
| 3 | 2 | 1 | 59 |
| 4 | 2 | 2 | 80 |
檢索結果
| 張三 | 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
只匹配右表存在的信息
全聯結
FULL JOIN \ FULL OUTER JOIN
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 STUDENT11.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 為什么使用視圖
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 TRANSACTIONROLLBACK 事務回滾
-- 插入數據,如果插入失敗回滾輸出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; ENDSAVE 保留點
對于簡單的事務可以使用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_NAME15.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)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Pandas入门超详细教程,看了超简单
- 下一篇: mysql nlssort_nlssor