Ⅰ sql 程序解釋
id小於500就繼續循環。假設表內沒有ID為0的書籍。
輸出:
1--對應的書籍名稱
3--對應的書籍名稱
5--對應的書籍名稱
......
7--對應的書籍名稱
9--對應的書籍名稱
11--對應的書籍名稱
......
一直循環
......
495--對應的書籍名稱
497--對應的書籍名稱
499--對應的書籍名稱
......
*** the end ***
是輸出奇數,jackyc23 的寫的很好很詳細
Ⅱ 資料庫SQL語言的程序問題
...你給0分!!!
Ⅲ sql中 事務的作用 什麼情況下要用事務 需要什麼條件
什麼是事務:事務是一個不可分割的工作邏輯單元,在資料庫系統上執行並發操作時事務是做為最小的控制單元來使用的。他包含的所有資料庫操作命令作為一個整體一起向系提交或撤消,這一組資料庫操作命令要麼都執行,要麼都不執行。
簡單例子銀行轉帳,如果甲把錢匯出去了,但是銀行發生了點問題,錢沒有匯到乙的錢包里,那錢怎麼辦。
這個時候如果用上事務,錢就會回滾到甲,一個減少,一個增加,要麼執行,要麼不執行
Ⅳ sql題目。
主鍵
單元格
Ⅳ SQL事務概念是什麼,舉個例子說明什麼樣的東西是事務,與程序又有何區別,
資料庫事務是構成單一邏輯工作單元的操作集合。
舉例:轉賬是生活中常見的操作,比如從A賬戶轉賬100元到B賬號。站在用戶角度而言,這是一個邏輯上的單一操作,然而在資料庫系統中,至少會分成兩個步驟來完成:
1、將A賬戶的金額減少100元
2、將B賬戶的金額增加100元。
與程序的區別:一個程序中包含多個事務。在關系資料庫中,一個事務可以是一條SQL語句,一組SQL語句或整個程序。
(5)sql程序最小工作單元擴展閱讀:
事務必須具備四個屬性,簡稱ACID屬性:
1、原子性(Atomicity):事務是一個完整的操作。事務的各步操作是不可分的(原子的);要麼都執行,要麼都不執行。
2、一致性(Consistency):當事務完成時,數據必須處於一致狀態。
3、隔離性(Isolation):對數據進行修改的所有並發事務是彼此隔離的,這表明事務必須是獨立的,它不應以任何方式依賴於或影響其他事務。
4、永久性(Durability):事務完成後,它對資料庫的修改被永久保持,事務日誌能夠保持事務的永久性。
Ⅵ 高分求sql資料庫問題
SQL資料庫操作完全手冊
SQL資料庫完全手冊
日期:2001-3-24 0:47:00
出處:電腦報
作者:未知
SQL是Structured Quevy Language(結構化查詢語言)的縮寫。SQL是專為資料庫而建立的操作命令集,是一種功能齊全的資料庫語言。在使用它時,只需要發出「做什麼」的命令,「怎麼做」是不用使用者考慮的。SQL功能強大、簡單易學、使用方便,已經成為了資料庫操作的基礎,並且現在幾乎所有的資料庫均支持SQL。
##1 二、SQL資料庫數據體系結構
SQL資料庫的數據體系結構基本上是三級結構,但使用術語與傳統關系模型術語不同。在SQL中,關系模式(模式)稱為「基本表」(base table);存儲模式(內模式)稱為「存儲文件」(stored file);子模式(外模式)稱為「視圖」(view);元組稱為「行」(row);屬性稱為「列」(column)。名稱對稱如^00100009a^:
##1 三、SQL語言的組成
在正式學習SQL語言之前,首先讓我們對SQL語言有一個基本認識,介紹一下SQL語言的組成:
1.一個SQL資料庫是表(Table)的集合,它由一個或多個SQL模式定義。
2.一個SQL表由行集構成,一行是列的序列(集合),每列與行對應一個數據項。
3.一個表或者是一個基本表或者是一個視圖。基本表是實際存儲在資料庫的表,而視圖是由若干基本表或其他視圖構成的表的定義。
4.一個基本表可以跨一個或多個存儲文件,一個存儲文件也可存放一個或多個基本表。每個存儲文件與外部存儲上一個物理文件對應。
5.用戶可以用SQL語句對視圖和基本表進行查詢等操作。在用戶角度來看,視圖和基本表是一樣的,沒有區別,都是關系(表格)。
6.SQL用戶可以是應用程序,也可以是終端用戶。SQL語句可嵌入在宿主語言的程序中使用,宿主語言有FORTRAN,COBOL,PASCAL,PL/I,C和Ada語言等。SQL用戶也能作為獨立的用戶介面,供交互環境下的終端用戶使用。
##1 四、對資料庫進行操作
SQL包括了所有對資料庫的操作,主要是由4個部分組成:
1.數據定義:這一部分又稱為「SQL DDL」,定義資料庫的邏輯結構,包括定義資料庫、基本表、視圖和索引4部分。
2.數據操縱:這一部分又稱為「SQL DML」,其中包括數據查詢和數據更新兩大類操作,其中數據更新又包括插入、刪除和更新三種操作。
3.數據控制:對用戶訪問數據的控制有基本表和視圖的授權、完整性規則的描述,事務控制語句等。
4.嵌入式SQL語言的使用規定:規定SQL語句在宿主語言的程序中使用的規則。
下面我們將分別介紹:
##2 (一)數據定義
SQL數據定義功能包括定義資料庫、基本表、索引和視圖。
首先,讓我們了解一下SQL所提供的基本數據類型:(如^00100009b^)
1.資料庫的建立與刪除
(1)建立資料庫:資料庫是一個包括了多個基本表的數據集,其語句格式為:
CREATE DATABASE <資料庫名> 〔其它參數〕
其中,<資料庫名>在系統中必須是唯一的,不能重復,不然將導致數據存取失誤。〔其它參數〕因具體資料庫實現系統不同而異。
例:要建立項目管理資料庫(xmmanage),其語句應為:
CREATE DATABASE xmmanage
(2) 資料庫的刪除:將資料庫及其全部內容從系統中刪除。
其語句格式為:DROP DATABASE <資料庫名>
例:刪除項目管理資料庫(xmmanage),其語句應為:
DROP DATABASE xmmanage
2.基本表的定義及變更
本身獨立存在的表稱為基本表,在SQL語言中一個關系唯一對應一個基本表。基本表的定義指建立基本關系模式,而變更則是指對資料庫中已存在的基本表進行刪除與修改。
(1)基本表的定義:基本表是非導出關系,其定義涉及表名、列名及數據類型等,其語句格式為:
CREATE TABLE〔<資料庫名>.〕<表名>
(<列名> 數據類型 〔預設值〕 〔NOT NULL / NULL〕
〔,<列名> 數據類型 〔預設值〕 〔NOT NULL / NULL〕〕......
〔,UNIQUE (列名〔,列名〕......)〕
〔,PRIMARY KEY(列名)〕
〔,FOREIGN KEY(列名〔,列名〕......)REFERENCE <表名>(列名〔,列名〕......)〕
〔,CHECK(條件)〕 〔其它參數〕)
其中,〈資料庫名〉.〕指出將新建立的表存放於該資料庫中;
新建的表由兩部分組成:其一為表和一組列名,其二是實際存放的數據(即可在定義表的同時,直接存放數據到表中);
列名為用戶自定義的易於理解的名稱,列名中不能使用空格;
數據類型為上面所介紹的幾種標准數據類型;
〔NOT NULL/NULL〕指出該列是否允許存放空值,SQL語言支持空值的概念,所謂空值是「不知道」或「無意義」的值,值得注意的是數據「0」和空格都不是空值,系統一般默認允許為空值,所以當不允許為空值時,必須明確使用NOT NULL;
〔,UNIQUE〕將列按照其規定的順序進行排列,如不指定排列順序,則按列的定義順序排列;
〔PRIMARY KEY〕用於指定表的主鍵(即關系中的主屬性),實體完整性約束條件規定:主鍵必須是唯一的,非空的;
〔,FOREIGN KEY (列名〔,列名〕......) REFERENCE<表名>(列名〔,列名〕......)〕是用於指定外鍵參照完整性約束條件,FOREIGN KEY指定相關列為外鍵,其參照對象為另外一個表的指定列,即使用REFERENCE引入的外表中的列,當不指定外表列名時,系統將默認其列名與參照鍵的列名相同,要注意的是:使用外鍵時必須使用參照,另外數據的外鍵參照完整性約束條件規定:外鍵的值要麼與相對應的主鍵相同,要麼為空值(具體由實現系統不同而異)
〔,CHECK〕用於使用指定條件對存入表中的數據進行檢查,以確定其合法性,提高數據的安全性。
例:要建立一個學生情況表(student)
CREATE TABLE student //創建基本表student
(st_class CHAR(8),// 定義列st_class班級,數據類型為8位定長字元串
st_no CHAR(10) NOT NULL,//定義列st_no學號,類型為10位定長字元串,非空
st_name CHAR(8) NOT NULL,//定義列st_name姓名,類型為8位定長字元串,非空
st_sex CHAR(2),//定義列st_sex性別,類型為2位定長字元串
st_age SMALLINT,//定義列st_age年齡,類型為短整型
PRIMARY KEY (st_no))//定義st_no學號為主鍵。
例:要建立課程設置表(subject)
CREATE TABLE subject//創建基本表subject
(su_no CHAR(4) NOT NULL,// 定義列su_no課號,類型為4位定長字元串,非空
su_subject CHAR(20) NOT NULL,// 定義列su_subject課程名,類型為20位定長字元串,非空
su_credit INTEGER,// 定義列su_credit學分,類型為長整數
su_period INTEGER,//定義列su_period學時,類型為長整數
su_preno CHAR(4),//定義列su_preno先修課號,類型為4位定長字元串
PRIMARY KEY(su_no))//定義su_no課號為主鍵。
例:要建立學生選課表(score)
CREATE TABLE score //創建基本表score
(st_no CHAR(10),//定義列st_no學號,類型為10位定長字元串
su_no CHAR(4),//定義列su_no課號,類型為4位定長字元串
sc_score INTEGER NULL,//定義列sc_score,類型為長整形,可以為空值
FOREIGN KEY (st_no) REFERENCE student,//從表student中引入參照外鍵st_no,以確保本表與表student的關聯與同步
FOREIGN KEY (suno) REFERENCE subject)//從表subject中引入參照外鍵su_no,以確保本表與表subject的關聯與同步
(2)基本表的刪除:用以從資料庫中刪除一個基本表及其全部內容,其語句格式為:
DROP TABLE〔<資料庫名>.〕表名
例如:將上面建立的表都刪除
DROP TABLE student,subject,score
(3)基本表的修改:在基本表建立並使用一段時間後,可能需要根據實際要求對基本表的結構進行修改,即增加新的屬性或刪除屬性。
增加屬性的語句格式為:
ALTER TABLE 〔<資料庫名>.〕表名 ADD
(<列名> 數據類型 〔預設值〕 〔NOT NULL / NULL〕
〔,<列名> 數據類型〔預設值〕〔NOT NULL / NULL〕〕......
〔,UNIQUE (列名〔,列名〕......)〕
〔,PRIMARY KEY(列名)〕
〔,FOREIGN KEY(列名〔,列名〕......) REFERENCE <表名>(列名〔,列名〕......)〕
〔,CHECK(條件)〕〔其它參數〕)
例如:在基本表student中加入列stborn出生日期,數據類型為DATE,且不能為空值
ALTER TABLE student ADD (stborn DATE NOT NULL)
刪除屬性的語句格式為:
ALTER TABLE 〔<資料庫名>.〕表名 DROP
( <列名> 數據類型 〔預設值〕〔NOT NULL / NULL〕
〔,<列名> 數據類型 〔預設值〕〔NOT NULL / NULL〕〕......)
例如:將基本表student中的列st_age刪除
ALTER TABLE student DROP (st_age)
3.視圖定義與刪除
在SQL中,視圖是外模式一級數據結構的基本單位。它是從一個或幾個基本表中導出的表,是從現有基本表中抽取若乾子集組成用戶的「專用表」。這種構造方式必須使用SQL中的SELECT語句來實現。在定義一個視圖時,只是把其定義存放在系統的數據中,而並不直接存儲視圖對應的數據,直到用戶使用視圖時才去求得對應的數據。
(1)視圖的定義:定義視圖可以使用CREATE VIEW語句實現,其語句格式為:
CREATE VIEW 視圖名 AS SELECT語句
從一個基本表中導出視圖:
例:從基本表student中導出只包括女學生情況的視圖
CREATE VIEW WOMANVIEW AS //創建一個視圖WOMANVIEW
SELECT st_class,st_no,st_name,st_age //選擇列st_class,st_no,st_name,st_age顯示
FROM student //從基本表student引入
WHERE st_sex=『女』//引入條件為性別為「女」,注意字元變數都使用單引號引用
從多個基本表中導出視圖:
例如:從基本表student和score中導出只包括女學生且分數在60分以上的視圖
CREATEVIEW WOMAN_SCORE AS //定義視圖WOMANSCORE
SELECT student.st_class,student.st_no,student.st_name,student.st_age,score.sc_score //有選擇性顯示相關列
FROM student.score //從基本表student和score中引入
WHERE student.st_sex=『女』AND score.sc_score>=60 AND student.st_no=score.st_no //選擇條件:性別為「女」 且分數在60分以上。並使用st_no將兩表聯系起來。
以後如果進行這一視圖的應用,則只需使用語句
SELECT * FROM WOMAN_SCORE //其中「*」為通配符,代表所有元素
(2)視圖的刪除:用於刪除已不再使用的視圖,其語句格式如下:
DROP VIEW 視圖名
例:將上面建立的WOMAN_SCORE視圖刪除
DROP VIEW WOMAN_SCORE
4.索引的定義與刪除
索引屬於物理存儲概念,而不是邏輯的概念。在SQL中拋棄了索引概念,直接使用主鍵概念。值得一提的是,有些關系DBMS同時包括索引機制和主鍵機制,這里我們推薦使用主鍵機制,因為它對系統資源佔用較低且效率較高。
(1)索引的定義:索引是建立在基本表之上的,其語句格式為:
CREATE 〔UNIQUE〕 INDEX 索引名 ON
〔<資料庫名>.〕表名(列名 〔ASC/DESC〕〔,列名 〔ASC/DESC〕〕......)
這里,保留字UNIQUE表示基本表中的索引值不允許重復,若預設則表示索引值在表中允許重復;DESC表示按索引鍵降序排列,若預設或ASC表示升序排列。
例:對基本表student中的st_no和st_age建立索引,分別為升序與降序,且索引值不允許重復
CREATE UNIQUE INDEX STINDEX ON//創建索引STINDEX
student(st_no ASC,st_age DESC)//對student中的st_no和st_age建立索引
(2)索引的刪除:
DROP INDEX 索引名
例:刪除上面建立的索引STINDEX
DROP INDEX STINDEX
##2 (二)數據查詢
SQL是一種查詢功能很強的語言,只要是資料庫存在的數據,總能通過適當的方法將它從資料庫中查找出來。SQL中的查詢語句只有一個:SELECT,它可與其它語句配合完成所有的查詢功能。SELECT語句的完整語法,可以有6個子句。完整的語法如下:
SELECT 目標表的列名或列表達式集合
FROM 基本表或(和)視圖集合
〔WHERE條件表達式〕
〔GROUP BY列名集合
〔HAVING組條件表達式〕〕
〔ORDER BY列名〔集合〕…〕
整個語句的語義如下:從FROM子句中列出的表中,選擇滿足WHERE子句中給出的條件表達式的元組,然後按GROUPBY子句(分組子句)中指定列的值分組,再提取滿足HAVING子句中組條件表達式的那些組,按SELECT子句給出的列名或列表達式求值輸出。ORDER子句(排序子句)是對輸出的目標表進行重新排序,並可附加說明ASC(升序)或DESC(降序)排列。
在WHERE子句中的條件表達式F中可出現下列操作符和運算函數:
算術比較運算符:<,<=,>,>=,=,<>。
邏輯運算符:AND,OR,NOT。
集合運算符:UNION(並),INTERSECT(交),EXCEPT(差)。
集合成員資格運算符:IN,NOT IN
謂詞:EXISTS(存在量詞),ALL,SOME,UNIQUE。
聚合函數:AVG(平均值),MIN(最小值),MAX(最大值),SUM(和),COUNT(計數)。
F中運算對象還可以是另一個SELECT語句,即SELECT語句可以嵌套。
上面只是列出了WHERE子句中可出現的幾種主要操作,由於WHERE子句中的條件表達式可以很復雜,因此SELECT句型能表達的語義遠比其數學原形要復雜得多。
下面,我們以上面所建立的三個基本表為例,演示一下SELECT的應用:
1.無條件查詢
例:找出所有學生的的選課情況
SELECT st_no,su_no
FROM score
例:找出所有學生的情況
SELECT*
FROM student
「*」為通配符,表示查找FROM中所指出關系的所有屬性的值。
2.條件查詢
條件查詢即帶有WHERE子句的查詢,所要查詢的對象必須滿足WHERE子句給出的條件。
例:找出任何一門課成績在70以上的學生情況、課號及分數
SELECT UNIQUE student.st_class,student.st_no,student.st_name,student.st_sex,student.st_age,score.su_no,score.score
FROM student,score
WHERE score.score>=70 AND score.stno=student.st_no
這里使用UNIQUE是不從查詢結果集中去掉重復行,如果使用DISTINCT則會去掉重復行。另外邏輯運算符的優先順序為NOT→AND→OR。
例:找出課程號為c02的,考試成績不及格的學生
SELECT st_no
FROM score
WHERE su_no=『c02』AND score<60
3.排序查詢
排序查詢是指將查詢結果按指定屬性的升序(ASC)或降序(DESC)排列,由ORDER BY子句指明。
例:查找不及格的課程,並將結果按課程號從大到小排列
SELECT UNIQUE su_no
FROM score
WHERE score<60
ORDER BY su_no DESC
4.嵌套查詢
嵌套查詢是指WHERE子句中又包含SELECT子句,它用於較復雜的跨多個基本表查詢的情況。
例:查找課程編號為c03且課程成績在80分以上的學生的學號、姓名
SELECT st_no,st_name
FROM student
WHERE stno IN (SELECT st_no
FROM score
WHERE su_no=『c03』 AND score>80 )
這里需要明確的是:當查詢涉及多個基本表時用嵌套查詢逐次求解層次分明,具有結構程序設計特點。在嵌套查詢中,IN是常用到的謂詞。若用戶能確切知道內層查詢返回的是單值,那麼也可用算術比較運算符表示用戶的要求。
5.計算查詢
計算查詢是指通過系統提供的特定函數(聚合函數)在語句中的直接使用而獲得某些只有經過計算才能得到的結果。常用的函數有:
COUNT(*) 計算元組的個數
COUNT(列名) 對某一列中的值計算個數
SUM(列名) 求某一列值的總和(此列值是數值型)
AVG(列名) 求某一列值的平均值(此列值是數值型)
MAX(列名) 求某一列值中的最大值
MIN(列名) 求某一列值中的最小值
例:求男學生的總人數和平均年齡
SELECT COUNT(*),AVG(st_age)
FROM student
WHERE st_sex=『男』
例:統計選修了課程的學生的人數
SELECT COUNT(DISTINCT st_no)
FROM score
注意:這里一定要加入DISTINCT,因為有的學生可能選修了多門課程,但統計時只能按1人統計,所以要使用DISTINCT進行過濾。
##2 (三) 數據更新
數據更新包括數據插入、刪除和修改操作。它們分別由INSERT語句,DELETE語句及UPDATE語句完成。這些操作都可在任何基本表上進行,但在視圖上有所限制。其中,當視圖是由單個基本表導出時,可進行插入和修改操作,但不能進行刪除操作;當視圖是從多個基本表中導出時,上述三種操作都不能進行。
1.數據插入
將數據插入SQL的基本表有兩種方式:一種是單元組的插入,另一種是多元組的插入。
單元組的插入:向基本表score中插入一個成績元組(100002,c02,95),可使用以下語句:
INSERT INTO score(st_no,su_no,score) VALUES(『100002』,『c02』,95)
由此,可以給出單元組的插入語句格式:
INSERT INTO表名(列名1〔,列名2〕…) VALUES(列值1〔,列值2〕…)
其中,列名序列為要插入值的列名集合,列值序列為要插入的對應值。若插入的是一個表的全部列值,則列名可以省略不寫如上面的(st_no,su_no,score)可以省去;若插入的是表的部分列值,則必須列出相應列名,此時,該關系中未列出的列名取空值。
多元組的插入:這是一種把SELECT語句查詢結果插入到某個已知的基本表中的方法。
例如:需要在表score中求出每個學生的平均成績,並保留在某個表中。此時可以先創建一個新的基本表stu_avggrade,再用INSERT語句把表score中求得的每一個學生的平均成績(用SELECT求得)插入至stu_avggrade中。
CREATE TABLE stu_avggrade
(st_no CHAR(10) NOT NULL,//定義列st_no學號,類型為10位定長字元串,非空
age_grade SMALLINT NOT NULL )// 定義列age_grade平均分,類型為短整形,非空
INSERT INTO stu_avggrade(st_no,age_grade)
SELECT st_no,AVG(score)
FROM score
GROUP BY st_no //因為要求每一個學生所有課程的平均成績,必須按學號分組進行計算。
2.數據刪除
SQL的刪除操作是指從基本表中刪除滿足WHERE<條件表達式>的記錄。如果沒有WHERE子句,則刪除表中全部記錄,但表結構依然存在。其語句格式為:
DELETE FROM表名〔WHERE 條件表達式〕
下面舉例說明:
單元組的刪除:把學號為100002的學生從表student中刪除,可用以下語句:
DELETE FROM student
WHERE st_no=『100002』//因為學號為100002的學生在表student中只有一個,所以為單元組的刪除
多元組的刪除:學號為100002的成績從表score中刪除,可用以下語句:
DELETE FROM score
WHERE st_no=『100002』//由於學號為100002的元組在表score中可能有多個,所以為多元組刪除
帶有子查詢的刪除操作:刪除所有不及格的學生記錄,可用以下語句
DELETE FROM student
WHERE st_no IN
(SELETE st_no
FROM score
WHERE score<60)
3.數據修改
修改語句是按SET子句中的表達式,在指定表中修改滿足條件表達式的記錄的相應列值。其語句格式如下:
UPDATE 表名 SET 列名=列改變值〔WHERE 條件表達式〕
例:把c02的課程名改為英語,可以用下列語句:
UPDATE subject
SET su_subject=『英語』
WHERE su_no=『c02』
例:將課程成績達到70分的學生成績,再提高10%
UPDATE score
SET score=1.1*score
WHERE score>=70
SQL的刪除語句和修改語句中的WHERE子句用法與SELECT中WHERE子句用法相同。數據的刪除和修改操作,實際上要先做SELECT查詢操作,然後再把找到的元組刪除或修改。
##2 (四) 數據控制
由於資料庫管理系統是一個多用戶系統,為了控制用戶對數據的存取權利,保持數據的共享及完全性,SQL語言提供了一系列的數據控制功能。其中,主要包括安全性控制、完整性控制、事務控制和並發控制。
1.安全性控制
數據的安全性是指保護資料庫,以防非法使用造成數據泄露和破壞。保證數據安全性的主要方法是通過對資料庫存取權力的控制來防止非法使用資料庫中的數據。即限定不同用戶操作不同的數據對象的許可權。
存取權控制包括權力的授與、檢查和撤消。權力授與和撤消命令由資料庫管理員或特定應用人員使用。系統在對資料庫操作前,先核實相應用戶是否有權在相應數據上進行所要求的操作。
(1)權力授與:權力授與有資料庫管理員專用的授權和用戶可用的授權兩種形式。資料庫管理員專用授權命令格式如下:
|CONNECT |
GRANT|RESOURCE|TO 用戶名〔IDENTIFED BY 口令〕
|DBA |
其中,CONNECT表示資料庫管理員允許指定的用戶具有連接到資料庫的權力,這種授權是針對新用戶;RESOURCE表示允許用戶建立自己的新關系模式,用戶獲得CONNECT權力後,必須獲得RESOURCE權力才能創建自己的新表;DBA表示資料庫管理員將自己的特權授與指定的用戶。若要同時授與某用戶上述三種授權中的多種權力,則必須通過三個相應的GRANT命令指定。
另外,具有CONNECT和RESOURCE授權的用戶可以建立自己的表,並在自己建立的表和視圖上具有查詢、插入、修改和刪除的權力。但通常不能使用其他用戶的關系,除非能獲得其他用戶轉授給他的相應權力。
例:若允許用戶SSE連接到資料庫並可以建立他自己的關系,則可通過如下命令授與權力:
GRANT CONNECT TO SSE INENTIFIED BY BD1928
GRANT RESOURCE TO SSE
用戶可用的授權是指用戶將自己擁有的部分或全部權力轉授給其他用戶的命令形式,其命令格式如下:
|SELECT |
|INSERT |
|DELETE |
GRANT|UPDATE(列名1[,列名2]…)|ON|表名 |TO|用戶名|〔WITH GRANT OPTION〕
|ALTER | |視圖名| |PUBLIC|
|NDEX |
|ALL |
若對某一用戶同時授與多種操作權力,則操作命令符號可用「,」相隔。
PUBLIC 表示將權力授與資料庫的所有用戶,使用時要注意:
任選項WITH GRANT OPTION表示接到授權的用戶,具有將其所得到的同時權力再轉授給其他用戶權力。
例:如果將表student的查詢權授與所有用戶,可使用以下命令:
GRANT SELECT ON student TO PUBLIC
例:若將表subject的插入及修改權力授與用戶SSE並使得他具有將這種權力轉授他人的權力,則可使用以下命令:
GRANT INSERT,UPDATE(su_subject) ON subject TO SSE WITH GRANT OPTION
這里,UPDATE後面跟su_subject是指出其所能修改的列。
(2)權力回收:權力回收是指回收指定用戶原已授與的某些權力。與權力授與命令相匹配,權力回收也有資料庫管理員專用和用戶可用的兩種形式。
DBA專用的權力回收命令格式為:
|CONNECT |
REVOKE|RESOURCE|FROM用戶名
|DBA |
用戶可用的權力回收命令格式為:
|SELECT |
|INSERT |
|DELETE |
REVOKE|UPDATE(列名1〔,列名2〕…) |ON|表名 |FROM |用戶名|
|ALTER | |視圖名| |PUBLIC|
|INDEX |
|ALL |
例:回收用戶SSE的DBA權力:
REVOKE DBA FROM SSE
2.完整性控制
資料庫的完整性是指數據的正確性和相容性,這是資料庫理論中的重要概念。完整性控制的主要目的是防止語義上不正確的數據進入資料庫。關系系統中的完整性約束條件包括實體完整性、參照完整性和用戶定義完整性。而完整性約束條件的定義主要是通過CREATE TABLE語句中的〔CHECK〕子句來完成。另外,還有一些輔助命令可以進行數據完整性保護。如UNIQUE和NOT NULL,前者用於防止重復值進入資料庫,後者用於防止空值。
3.事務控制
事務是並發控制的基本單位,也是恢復的基本單位。在SQL中支持事務的概念。所謂事務,是用戶定義的一個操作序列(集合),這些操作要麼都做,要麼一個都不做,是一個不可分割的整體。一個事務通常以BEGIN TRANSACTION開始,以COMMIT或ROLLBACK結束。
SQL提供了事務提交和事務撤消兩種命令:
(1)事務提交:事務提交的命令為:
COMMIT 〔WORK〕
事務提交標志著對資料庫的某種應用操作成功地完成,所有對資料庫的操作都必須作為事務提交給系統時才有效。事務一經提交就不能撤消。
(2)事務撤消:事務撤消的命令是:
ROLLBACK 〔WORK〕
事務撤消標志著相應事務對資料庫操作失敗,因而要撤消對資料庫的改變,即要「回滾」到相應事務開始時的狀態。
當系統非正常結束時(如掉電、系統死機),將自動執行ROLLBACK命令
SQL還提供了自動提交事務的機制,其命令為:
SET AUTO COMMIT ON
其對應的人工工作方式命令為:
SET AUTO COMMIT OFF
一旦規定了自動提交事務方式,則系統將每條SQL命令視為一個事務,並在命令成功執行完成時自動地完成事務提交。
4.並發控制
資料庫作為共享資源,允許多個用戶程序並行地存取數據。當多個用戶並行地操作資料庫時,需要通過並發控制對它們加以協調、控制,以保證並發操作的正確執行,並保證資料庫的一致性。
在SQL中,並發控制採用封鎖技術實現,當一個事務欲對某個數據對象操作時,可申請對該對象加鎖,取得對數據對象的一定控制,以限制其他事務對該對象的操作。其語句格式為:
|SHARE |
LOCK TABLE 表名(或表名集合)IN |EXCLUSVE |MODE 〔NOWAIT]
|SHARE UPDATE|
其中,表名(或表名集合)中指出封鎖對象,若為多個表名,則各個表名間以「,」相隔;任選項NOWAIT表示多個用戶要求封鎖相同的關系時,後來提出的要求會被立即退回去,否則會等待該資源釋放。
SHARE表示共享封鎖方式;EXCLUSIVE表示獨占封鎖方式;SHARE UPDAE表示共享更新封鎖方式。其中共享封鎖方式允許其他事務讀同一數據,但防止其他事務對已封鎖的表進行更新,該鎖主要防止在表的兩次查詢之間對該表的改動;共享更新封鎖SHARE UPDATE是一個行封鎖機制,
Ⅶ SQL事務概念問題
所謂事務是用戶定義的一個資料庫操作序列,這些操作要麼全做要麼全不做,是一個不可分割的工作單位。例如,在關系資料庫中,一個事務可以是一條SQL語句、一組SQL語句或整個程序。
事務和程序是兩個概念。一般地講,一個程序中包含多個事務。
事務的開始與結束可以由用戶顯式控制。如果用戶沒有顯式地定義事務,則由DBMS按預設規定自動劃分事
務。在SQL語言中,定義事務的語句有三條:
BEGIN TRANSACTION
COMMIT
ROLLBACK
Ⅷ SQL語句執行流程與順序原理解析
SQL語句執行流程與順序原理解析
Oracle語句執行流程
第一步:客戶端把語句發給伺服器端執行
當我們在客戶端執行SQL語句時,客戶端會把這條SQL語句發送給伺服器端,讓伺服器端的進程來處理這語句。也就是說,Oracle 客戶端是不會做任何的操作,他的主要任務就是把客戶端產生的一些SQL語句發送給伺服器端。伺服器進程從用戶進程把信息接收到後, 在PGA 中就要此進程分配所需內存,存儲相關的信息,如:在會話內存存儲相關的登錄信息等。
雖然在客戶端也有一個資料庫進程,但是,這個進程的作用跟伺服器上的進程作用是不相同的,伺服器上的資料庫進程才會對SQL 語句進行相關的處理。不過,有個問題需要說明,就是客戶端的進程跟伺服器的進程是一一對應的。也就是說,在客戶端連接上伺服器後,在客戶端與伺服器端都會形成一個進程,客戶端上的我們叫做客戶端進程,而伺服器上的我們叫做伺服器進程。
第二步:語句解析
當客戶端把SQL語句傳送到伺服器後,伺服器進程會對該語句進行解析。這個解析的工作是在伺服器端所進行的,解析動作又可分為很多小動作。
1)查詢高速緩存(library cache)
伺服器進程在接到客戶端傳送過來的SQL語句時,不會直接去資料庫查詢。伺服器進程把這個SQL語句的字元轉化為ASCII等效數字碼,接著這個ASCII碼被傳遞給一個HASH函數,並返回一個hash值,然後伺服器進程將到shared pool中的library cache(高速緩存)中去查找是否存在相同的hash值。如果存在,伺服器進程將使用這條語句已高速緩存在SHARED POOL的library cache中的已分析過的版本來執行,省去後續的解析工作,這便是軟解析。若調整緩存中不存在,則需要進行後面的步驟,這便是硬解析。硬解析通常是昂貴的操作,大約占整個SQL執行的70%左右的時間,硬解析會生成執行樹,執行計劃,等等。
所以,採用高速數據緩存的話,可以提高SQL 語句的查詢效率。其原因有兩方面:一方面是從內存中讀取數據要比從硬碟中的數據文件中讀取數據效率要高,另一方面也是因為避免語句解析而節省了時間。
不過這里要注意一點,這個數據緩存跟有些客戶端軟體的數據緩存是兩碼事。有些客戶端軟體為了提高查詢效率,會在應用軟體的客戶端設置數據緩存。由於這些數據緩存的存在,可以提高客戶端應用軟體的查詢效率。但是,若其他人在伺服器進行了相關的修改,由於應用軟體數據緩存的存在,導致修改的數據不能及時反映到客戶端上。從這也可以看出,應用軟體的數據緩存跟資料庫伺服器的高速數據緩存不是一碼事。
2)語句合法性檢查(data dict cache)
當在高速緩存中找不到對應的SQL語句時,則伺服器進程就會開始檢查這條語句的合法性。這里主要是對SQL語句的語法進行檢查,看看其是否合乎語法規則。如果伺服器進程認為這條SQL語句不符合語法規則的時候,就會把這個錯誤信息反饋給客戶端。在這個語法檢查的過程中,不會對SQL語句中所包含的表名、列名等等進行檢查,只是檢查語法。
3)語言含義檢查(data dict cache)
若SQL 語句符合語法上的定義的話,則伺服器進程接下去會對語句中涉及的表、索引、視圖等對象進行解析,並對照數據字典檢查這些對象的名稱以及相關結構,看看這些欄位、表、視圖等是否在資料庫中。如果表名與列名不準確的話,則資料庫會就會反饋錯誤信息給客戶端。
所以,有時候我們寫select語句的時候,若語法與表名或者列名同時寫錯的話,則系統是先提示說語法錯誤,等到語法完全正確後再提示說列名或表名錯誤。
4)獲得對象解析鎖(control structer)
當語法、語義都正確後,系統就會對我們需要查詢的對象加鎖。這主要是為了保障數據的一致性,防止我們在查詢的過程中,其他用戶對這個對象的結構發生改變。
5)數據訪問許可權的核對(data dict cache)
當語法、語義通過檢查之後,客戶端還不一定能夠取得數據,伺服器進程還會檢查連接用戶是否有這個數據訪問的許可權。若用戶不具有數據訪問許可權的話,則客戶端就不能夠取得這些數據。要注意的是資料庫伺服器進程先檢查語法與語義,然後才會檢查訪問許可權。
6)確定最佳執行計劃
當語法與語義都沒有問題許可權也匹配,伺服器進程還是不會直接對資料庫文件進行查詢。伺服器進程會根據一定的規則,對這條語句進行優化。在執行計劃開發之前會有一步查詢轉換,如:視圖合並、子查詢解嵌套、謂語前推及物化視圖重寫查詢等。為了確定採用哪個執行計劃,Oracle還需要收集統計信息確定表的訪問聯結方法等,最終確定可能的最低成本的執行計劃。
不過要注意,這個優化是有限的。一般在應用軟體開發的過程中,需要對資料庫的sql語句進行優化,這個優化的作用要大大地大於伺服器進程的自我優化。
當伺服器進程的優化器確定這條查詢語句的最佳執行計劃後, 就會將這條SQL語句與執行計劃保存到數據高速緩存(library cache)。如此,等以後還有這個查詢時,就會省略以上的語法、語義與許可權檢查的步驟,而直接執行SQL語句,提高SQL語句處理效率。
第三步:綁定變數賦值
如果SQL語句中使用了綁定變數,掃描綁定變數的聲明,給綁定變數賦值,將變數值帶入執行計劃。若在解析的第一個步驟,SQL在高速緩沖中存在,則直接跳到該步驟。
第四步:語句執行
語句解析只是對SQL語句的語法進行解析,以確保伺服器能夠知道這條語句到底表達的是什麼意思。等到語句解析完成之後,資料庫伺服器進程才會真正的執行這條SQL語句。
對於SELECT語句:
1)首先伺服器進程要判斷所需數據是否在db buffer存在,如果存在且可用,則直接獲取該數據而不是從資料庫文件中去查詢數據,同時根據LRU 演算法增加其訪問計數;
2)若數據不在緩沖區中,則伺服器進程將從資料庫文件中查詢相關數據,並把這些數據放入到數據緩沖區中(buffer cache)。
其中,若數據存在於db buffer,其可用性檢查方式為:查看db buffer塊的頭部是否有事務,如果有事務,則從回滾段中讀取數據;如果沒有事務,則比較select的scn和db buffer塊頭部的scn,如果前者小於後者,仍然要從回滾段中讀取數據;如果前者大於後者,說明這是一非臟緩存,可以直接讀取這個db buffer塊的中內容。
對於DML語句(insert、delete、update):
1)檢查所需的資料庫是否已經被讀取到緩沖區緩存中。如果已經存在緩沖區緩存,則直接執行步驟3;
2)若所需的資料庫並不在緩沖區緩存中,則伺服器將數據塊從數據文件讀取到緩沖區緩存中;
3)對想要修改的表取得的數據行鎖定(Row Exclusive Lock),之後對所需要修改的數據行取得獨占鎖;
4)將數據的Redo記錄復制到redo log buffer;
5)產生數據修改的undo數據;
6)修改db buffer;
7)dbwr將修改寫入數據文件;
其中,第2步,伺服器將數據從數據文件讀取到db buffer經經歷以下步驟:
1)首先伺服器進程將在表頭部請求TM鎖(保證此事務執行過程其他用戶不能修改表的結構),如果成功加TM鎖,再請求一些行級鎖(TX鎖),如果TM、TX鎖都成功加鎖,那麼才開始從數據文件讀數據。
2)在讀數據之前,要先為讀取的文件准備好buffer空間。伺服器進程需要掃描LRU list尋找free db buffer,掃描的過程中,伺服器進程會把發現的所有已經被修改過的db buffer注冊到dirty list中。如果free db buffer及非臟數據塊緩沖區不足時,會觸發dbwr將dirty buffer中指向的緩沖塊寫入數據文件,並且清洗掉這些緩沖區來騰出空間緩沖新讀入的數據。
3)找到了足夠的空閑buffer,伺服器進程將從數據文件中讀入這些行所在的每一個數據塊(db block)(DB BLOCK是ORACLE的最小操作單元,即使你想要的數據只是DB BLOCK中很多行中的一行或幾行,ORACLE也會把這個DB BLOCK中的所有行都讀入Oracle DB BUFFER中)放入db buffer的空閑的區域或者覆蓋已被擠出LRU list的非臟數據塊緩沖區,並且排列在LRU列表的頭部,也就是在數據塊放入db buffer之前也是要先申請db buffer中的鎖存器,成功加鎖後,才能讀數據到db buffer。
若數據塊已經存在於db buffer cache(有時也稱db buffer或db cache),即使在db buffer中找到一個沒有事務,而且SCN比自己小的非臟緩存數據塊,伺服器進程仍然要到表的頭部對這條記錄申請加鎖,加鎖成功才能進行後續動作,如果不成功,則要等待前面的進程解鎖後才能進行動作(這個時候阻塞是tx鎖阻塞)。
在記redo日誌時,其具體步驟如下:
1)數據被讀入到db buffer後,伺服器進程將該語句所影響的並被讀入db buffer中的這些行數據的rowid及要更新的原值和新值及scn等信息從PGA逐條的寫入redo log buffer中。在寫入redo log buffer之前也要事先請求redo log buffer的鎖存器,成功加鎖後才開始寫入。
2)當寫入達到redo log buffer大小的三分之一或寫入量達到1M或超過三秒後或發生檢查點時或者dbwr之前發生,都會觸發lgwr進程把redo log buffer的數據寫入磁碟上的redo file文件中(這個時候會產生log file sync等待事件)。
3)已經被寫入redo file的redo log buffer所持有的鎖存器會被釋放,並可被後來的寫入信息覆蓋,redo log buffer是循環使用的。Redo file也是循環使用的,當一個redo file寫滿後,lgwr進程會自動切換到下一redo file(這個時候可能出現log file switch(check point complete)等待事件)。如果是歸檔模式,歸檔進程還要將前一個寫滿的redo file文件的內容寫到歸檔日誌文件中(這個時候可能出現log file switch(archiving needed)。
在為事務建立undo信息時,其具體步驟如下:
1)在完成本事務所有相關的redo log buffer之後,伺服器進程開始改寫這個db buffer的塊頭部事務列表並寫入scn(一開始scn是寫在redo log buffer中的,並未寫在db buffer)。
2)然後包含這個塊的頭部事務列表及scn信息的數據副本放入回滾段中,將這時回滾段中的信息稱為數據塊的「前映像」,這個「前映像」用於以後的回滾、恢復和一致性讀。(回滾段可以存儲在專門的回滾表空間中,這個表空間由一個或多個物理文件組成,並專用於回滾表空間,回滾段也可在其它表空間中的數據文件中開辟)。
在修改信息寫入數據文件時,其具體步驟如下:
1)改寫db buffer塊的數據內容,並在塊的頭部寫入回滾段的地址。
2)將db buffer指針放入dirty list。如果一個行數據多次update而未commit,則在回滾段中將會有多個「前映像」,除了第一個「前映像」含有scn信息外,其他每個"前映像"的頭部都有scn信息和"前前映像"回滾段地址。一個update只對應一個scn,然後伺服器進程將在dirty list中建立一條指向此db buffer塊的指針(方便dbwr進程可以找到dirty list的db buffer數據塊並寫入數據文件中)。接著伺服器進程會從數據文件中繼續讀入第二個數據塊,重復前一數據塊的動作,數據塊的讀入、記日誌、建立回滾段、修改數據塊、放入dirty list。
3)當dirty queue的長度達到閥值(一般是25%),伺服器進程將通知dbwr把臟數據寫出,就是釋放db buffer上的鎖存器,騰出更多的free db buffer。前面一直都是在說明oracle一次讀一個數據塊,其實oracle可以一次讀入多個數據塊(db_file_multiblock_read_count來設置一次讀入塊的個數)
當執行commit時,具體步驟如下:
1)commit觸發lgwr進程,但不強制dbwr立即釋放所有相應db buffer塊的鎖。也就是說有可能雖然已經commit了,但在隨後的一段時間內dbwr還在寫這條sql語句所涉及的數據塊。表頭部的行鎖並不在commit之後立即釋放,而是要等dbwr進程完成之後才釋放,這就可能會出現一個用戶請求另一用戶已經commit的資源不成功的現象。
2)從Commit和dbwr進程結束之間的時間很短,如果恰巧在commit之後,dbwr未結束之前斷電,因為commit之後的數據已經屬於數據文件的內容,但這部分文件沒有完全寫入到數據文件中。所以需要前滾。由於commit已經觸發lgwr,這些所有未來得及寫入數據文件的更改會在實例重啟後,由smon進程根據重做日誌文件來前滾,完成之前commit未完成的工作(即把更改寫入數據文件)。
3)如果未commit就斷電了,因為數據已經在db buffer更改了,沒有commit,說明這部分數據不屬於數據文件。由於dbwr之前觸發lgwr也就是只要數據更改,(肯定要先有log)所有dbwr在數據文件上的修改都會被先一步記入重做日誌文件,實例重啟後,SMON進程再根據重做日誌文件來回滾。
其實smon的前滾回滾是根據檢查點來完成的,當一個全部檢查點發生的時候,首先讓LGWR進程將redologbuffer中的所有緩沖(包含未提交的重做信息)寫入重做日誌文件,然後讓dbwr進程將dbbuffer已提交的緩沖寫入數據文件(不強制寫未提交的)。然後更新控制文件和數據文件頭部的SCN,表明當前資料庫是一致的,在相鄰的兩個檢查點之間有很多事務,有提交和未提交的。
當執行rollback時,具體步驟如下:
伺服器進程會根據數據文件塊和db buffer中塊的頭部的事務列表和SCN以及回滾段地址找到回滾段中相應的修改前的副本,並且用這些原值來還原當前數據文件中已修改但未提交的改變。如果有多個」前映像「,伺服器進程會在一個「前映像」的頭部找到「前前映像」的回滾段地址,一直找到同一事務下的最早的一個「前映像」為止。一旦發出了commit,用戶就不能rollback,這使得commit後dbwr進程還沒有全部完成的後續動作得到了保障。
第五步:提取數據
當語句執行完成之後,查詢到的數據還是在伺服器進程中,還沒有被傳送到客戶端的用戶進程。所以,在伺服器端的進程中,有一個專門負責數據提取的一段代碼。他的作用就是把查詢到的數據結果返回給用戶端進程,從而完成整個查詢動作。
從這整個查詢處理過程中,我們在資料庫開發或者應用軟體開發過程中,需要注意以下幾點:
一是要了解資料庫緩存跟應用軟體緩存是兩碼事情。資料庫緩存只有在資料庫伺服器端才存在,在客戶端是不存在的。只有如此,才能夠保證資料庫緩存中的內容跟資料庫文件的內容一致。才能夠根據相關的規則,防止數據臟讀、錯讀的發生。而應用軟體所涉及的數據緩存,由於跟資料庫緩存不是一碼事情,所以,應用軟體的數據緩存雖然可以提高數據的查詢效率,但是,卻打破了數據一致性的要求,有時候會發生臟讀、錯讀等情況的發生。所以,有時候,在應用軟體上有專門一個功能,用來在必要的時候清除數據緩存。不過,這個數據緩存的清除,也只是清除本機上的數據緩存,或者說,只是清除這個應用程序的數據緩存,而不會清除資料庫的數據緩存。
二是絕大部分SQL語句都是按照這個處理過程處理的。我們DBA或者基於Oracle資料庫的開發人員了解這些語句的處理過程,對於我們進行涉及到SQL語句的開發與調試,是非常有幫助的。有時候,掌握這些處理原則,可以減少我們排錯的時間。特別要注意,資料庫是把數據查詢許可權的審查放在語法語義的後面進行檢查的。所以,有時會若光用資料庫的許可權控制原則,可能還不能滿足應用軟體許可權控制的需要。此時,就需要應用軟體的前台設置,實現許可權管理的要求。而且,有時應用資料庫的許可權管理,也有點顯得繁瑣,會增加伺服器處理的工作量。因此,對於記錄、欄位等的查詢許可權控制,大部分程序涉及人員喜歡在應用程序中實現,而不是在資料庫上實現。
Oracle SQL語句執行順序
(8)SELECT (9) DISTINCT (11) <select_list>
(1) FROM <left_table>
(3) <join_type> JOIN <right_table>
(2) ON <join_condition>
(4) WHERE <where_condition>
(5) GROUP BY <group_by_list>
(6) WITH {CUBE | ROLLUP}
(7) HAVING <having_condition>
(10) ORDER BY <order_by_list>
1)FROM:對FROM子句中的表執行笛卡爾積(交叉聯接),生成虛擬表VT1。
2)ON:對VT1應用ON篩選器,只有那些使為真才被插入到TV2。
3)OUTER (JOIN):如果指定了OUTER JOIN(相對於CROSS JOIN或INNER JOIN),保留表中未找到匹配的行將作為外部行添加到VT2,生成TV3。如果FROM子句包含兩個以上的表,則對上一個聯接生成的結果表和下一個表重復執行步驟1到步驟3,直到處理完所有的表位置。
4)WHERE:對TV3應用WHERE篩選器,只有使為true的行才插入TV4。
5)GROUP BY:按GROUP BY子句中的列列表對TV4中的行進行分組,生成TV5。
6)CUTE|ROLLUP:把超組插入VT5,生成VT6。
7)HAVING:對VT6應用HAVING篩選器,只有使為true的組插入到VT7。
8)SELECT:處理SELECT列表,產生VT8。
9)DISTINCT:將重復的行從VT8中刪除,產品VT9。
10)ORDER BY:將VT9中的行按ORDER BY子句中的列列表順序,生成一個游標(VC10),生成表TV11,並返回給調用者。
以上每個步驟都會產生一個虛擬表,該虛擬表被用作下一個步驟的輸入。這些虛擬表對調用者(客戶端應用程序或者外部查詢)不可用。只有最後一步生成的表才會會給調用者。如果沒有在查詢中指定某一個子句,將跳過相應的步驟。
Ⅸ sql server 存儲過程
在執行存儲過程時,我們常遇到執行超時的情況。如果是因為要處理的數據過多,修改流程復雜等原因的話,如以用以下方法解決:在存儲過程的處理工作中加上事務管理:SET TRANSACTION ISOLATION LEVEL REPEATABLE READ --->要這行
BEGIN TRAN /* 這里是程序處理代碼段*/commit transaction
QuitWithRollback:
IF (@@TRANCOUNT > 0)
BEGIN
ROLLBACK TRANSACTION
END 以下是事務相關的知識:BEGIN TRANSACTION--開始事務DECLARE @errorSun INT --定義錯誤計數器SET @errorSun=0 --沒錯為0UPDATE a SET id=232 WHERE a=1 --事務操作SQL語句SET @errorSun=@errorSun+@@ERROR --累計是否有錯UPDATE aa SET id=2 WHERE a=1 --事務操作SQL語句SET @errorSun=@errorSun+@@ERROR --累計是否有錯IF @errorSun<>0 BEGIN PRINT '有錯誤,回滾'ROLLBACK TRANSACTION--事務回滾語句END ELSE BEGIN PRINT '成功,提交'COMMIT TRANSACTION--事務提交語句END1.什麼是事務:事務是一個不可分割的工作邏輯單元,在資料庫系統上執行並發操作時事務是做為最小的控制單元來使用的。他包含的所有資料庫操作命令作為一個整體一起向系提交或撤消,這一組資料庫操作命令要麼都執行,要麼都不執行。2.事務的語句開始事物:BEGIN TRANSACTION 提交事物:COMMIT TRANSACTION 回滾事務:ROLLBACK TRANSACTION3.事務的4個屬性①原子性(Atomicity):事務中的所有元素作為一個整體提交或回滾,事務的個元素是不可分的,事務是一個完整操作。②一致性(Consistemcy):事物完成時,數據必須是一致的,也就是說,和事物開始之前,數據存儲中的數據處於一致狀態。保證數據的無損。③隔離性(Isolation):對數據進行修改的多個事務是彼此隔離的。這表明事務必須是獨立的,不應該以任何方式以來於或影響其他事務。④持久性(Durability):事務完成之後,它對於系統的影響是永久的,該修改即使出現系統故障也將一直保留,真實的修改了資料庫4.事務的保存點 SAVE TRANSACTION 保存點名稱 --自定義保存點的名稱和位置 ROLLBACK TRANSACTION 保存點名稱 --回滾到自定義的保存點 二事例 所謂事務是指一組邏輯操作單元,它使數據從一種狀態變換到另一種狀態。包括四個特性:1、原子性 就是事務應作為一個工作單元,事務處理完成,所有的工作要麼都在資料庫中保存下來,要麼完全回滾,全部不保留2、一致性 事務完成或者撤銷後,都應該處於一致的狀態3、隔離性 多個事務同時進行,它們之間應該互不幹擾.應該防止一個事務處理其他事務也要修改的數據時, 不合理的存取和不完整的讀取數據4、持久性 事務提交以後,所做的工作就被永久的保存下來 示例:創建一個存儲過程,向兩個表中同時插入數據Create proc RegisterUser(@usrName varchar(30),@usrPasswd varchar(30),@age int,@sex varchar(10),@PhoneNum varchar(20),@Address varchar(50) )as beginbegin traninsert into userinfo(userName,userPasswd)values(@usrName,@usrPasswd)if @@error<>0begin rollback tranreturn -1endinsert into userdoc(userName,age,sex,PhoneNumber,Address)values(@Usrname,@age,@sex,@PhoneNum,@Address)if @@error<>0begin rollback tranreturn -1endcommit tranreturn 0end事務的分類按事務的啟動與執行方式,可以將事務分為3類:顯示事務 也稱之為用戶定義或用戶指定的事務,即可以顯式地定義啟動和結束的事務。分布式事務屬於顯示事務自動提交事務默認事務管理模式。如果一個語句成功地完成,則提交該語句;如果遇到錯誤,則回滾該語句。隱性事務當連接以此模式進行操作時,sql將在提交或回滾當前事務後自動啟動新事務。無須描述事務的開始,只需提交或回滾每個事務。它生成連續的事務鏈。一、顯示事務通過begin transacton、commit transaction、commit work、rollback transaction或rollback work等語句完成。1、啟動事務格式:begin tran 事務名或變數 with mark 描述2、結束事務格式:commit tran 事務名或變數 (事務名與begin tran中的事務名一致或commit work 但此沒有參數3、回滾事務 rollback tran 事務名或變數 | savepoint_name | savepoint_variable 或rollback work 說明:清除自事務的起點或到某個保存點所做的所有數據修改4、在事務內設置保存點格式:save tran savepoint_name | savepoint_variable 示例:use bookdbgobegin tran mytraninsert into book values(9,"windows2000',1,22,'出版社')save tran mysavedelete book where book_id=9rollback tran mysavecommit trangoselect * from bookgo可以知道,上面的語句執行後,在book中插入了一筆記錄,而並沒有刪除。因為使用rollback tran mysave 語句將操作回滾到了刪除前的保存點處。5、標記事務格式:with mark 例:使用資料庫標記將日誌恢復到預定義時間點的語句 在事務日誌中置入一個標記。請注意,被標記的事務至少須提交一個更新,以標記該日誌。BEGIN TRAN MyMark WITH MARK UPDATE pubs.dbo.LastLogMark SET MarkTime = GETDATE() COMMIT TRAN MyMark 按照您常用的方法備份事務日誌。BACKUP LOG pubs TO DISK='C:/Backups/Fullbackup.bak' WITH INIT 現在您可以將資料庫恢復至日誌標記點。首先恢復資料庫,並使其為接受日誌恢復做好准備。 RESTORE DATABASE pubs FROM DISK=N'C:/Backups/Fullbackup.bak' WITH NORECOVERY 現在將日誌恢復至包含該標記的時間點,並使其可供使用。請注意,STOPAT在資料庫正在執行大容量日誌時禁止執行。 RESTORE LOG pubs FROM DISK=N'C:/Backups/Logbackup.bak' WITH RECOVERY, STOPAT='02/11/2002 17:35:00'5、不能用於事務的操作創建資料庫 create database 修改資料庫 alter database 刪除資料庫 drop database 恢復資料庫 restore database 載入資料庫 load database 備份日誌文件 backup log 恢復日誌文件 restore log 更新統計數據 update statitics 授權操作 grant 復制事務日誌 mp tran 磁碟初始化 disk init 更新使用sp_configure後的系統配置 reconfigure二、自動提交事務 sql連接在begin tran 語句啟動顯式事務,或隱性事務模式設置為打開之前,將以自動提交模式進行操作。當提交或回滾顯式事務,或者關閉隱性事務模式時,將返回到自動提交模式。示例: 由於編譯錯誤,使得三個insert都沒執行use testgocreate table testback(cola int primary key ,colb char(3))goinsert into testback values(1,'aaa')insert into testback values(2,'bbb')insert into testback value(3,'ccc')goselect * from testbackgo 沒有任何結果返回三、隱式事務通過 API 函數或 Transact-SQL SET IMPLICIT_TRANSACTIONS ON 語句,將隱性事務模式設置為打開。下一個語句自動啟動一個新事務。當該事務完成時,再下一個 Transact-SQL 語句又將啟動一個新事務。當有大量的DDL 和DML命令執行時會自動開始,並一直保持到用戶明確提交為止,切換隱式事務可以用SET IMPLICIT_TRANSACTIONS 為連接設置隱性事務模式.當設置為 ON 時,SET IMPLICIT_TRANSACTIONS 將連接設置為隱性事務模式。當設置為 OFF 時,則使連接返回到自動提交事務模式 語句包括: alter table insert open create delete revoke drop select fetch truncate table grant update 示例: 下面使用顯式與隱式事務。它使用@@tracount函數演示打開的事務與關閉的事務:use testgoset nocount oncreate table t1(a int)goinsert into t1 values(1)goprint '使用顯式事務'begin traninsert into t1 values(2)print '事務外的事務數目:'+cast(@@trancount as char(5))commint tranprint '事務外的事務數目:'+cast(@@trancount as char(5))goprintgoset implicit_transactions on go print '使用隱式事務'goinsert into t1 values*4)print'事務內的事務數目:'+cast(@@trancount as char(5))commint tran print'事務外的事務數目:'+cast(@@trancount as char(5))go執行結果: 使用顯示事務事務內的事務數目:2 事務外的事務數目:1 使用隱式事務事務內的事務數目:1 事務外的事務數目:0四、分布式事務跨越兩個或多個資料庫的單個sql server中的事務就是分布式事務。與本地事務區別:必須由事務管理器管理,以盡量避免出現因網路故障而導致一個事務由某些資源管理器成功提交,但由另一些資源管理器回滾的情況。 sql server 可以由DTc microsoft distributed transaction coordinator 來支持處理分布式事務,可以使用 BEgin distributed transaction 命令啟動一個分布式事務處理 分二階段:A 准備階段 B 提交階段執行教程:1、sql 腳本或應用程序連接執行啟動分布式事務的sql語句2、執行該語句的sql在為事務中的主控伺服器3、腳本或應用程序對鏈接的伺服器執行分布式查詢,或對遠程伺服器執行遠程存儲過程。4、當執行了分布式查詢或遠程過程調用後,主控伺服器將自動調用msdtc以便登記分布式事務中鏈接的伺服器和遠程伺服器5、當腳本或應用程序發出commit或rollback語句時,主控sql將調用msdtc管理兩階段提交過程,或者通知鏈接的伺服器和遠程伺服器回滾其事務。