SQL_Server_2008完全学习之第八章Transact-SQL编程
1、Transact-SQL概述
?
Transact-SQL
1)結構化查詢語言(SQL)是由美國國家標準協(xié)會(ANSI,American National Standards Institute)和國際標準化組織(ISO,International Standards Organization)定義的標準,而Transact-SQL是Microsoft公司對標準的一個實現(xiàn)。
?
2)Transact-SQL語言是結構化查詢語言(SQL)的增強版本,與多種ANSISQL標準兼容,而且在標準的基礎上還進行了許多擴展。Transact-SQL代碼已成為SQL Server的核心。Transact-SQL在關系數(shù)據(jù)庫管理系統(tǒng)中實現(xiàn)數(shù)據(jù)的檢索、操縱和添加功能。
?
分類
1)在Microsoft SQL Server 2008系統(tǒng)中,Transact-SQL可以創(chuàng)建、維護、保護數(shù)據(jù)庫對象,并且可以操作對象中的數(shù)據(jù),所以Transact-SQL語言是一種完整的語言。根據(jù)T-SQL語言的執(zhí)行功能特點,可以將T-SQL語言分為三種基本類型
a)數(shù)據(jù)定義語言
b)數(shù)據(jù)操作語言
c)數(shù)據(jù)控制語言
?
2)其他常用類型
a)事務管理語言
b)流程控制語言
c)附加的語言元素
?
2、常量與變量
?
變量
1)聲明
DECLARE
{@local_variable[AS]data_type
|@cursor_variable_name CURSOR
}[,...n]
?
2)要給聲明的局部變量賦值,可以使用SET或SETECT語句,格式如下:
a) SET @local_variable = expression
b) SETECT @local_variable=expression[,...n]
?
declare?@userName?nvarchar(20)--set?@userName='張三'
select?@userName?=?(SELECT?UserName?from?[User]?where?UserID=196)
select?@userName
?
3、運算符
?
1)算術運算符:[+、-、*、/、%]
2)位運算符
a)【&】位與邏輯運算,從兩個表達式中取對應的位。當且僅當輸入表達式中兩個位的值都為1時,結果中的位才被設置為1,否則,結果中的位被設置為0。
b)【|】位或邏輯運管,從兩個表達式中取對應的位。如果輸入表達式中兩個只要有一個的值為1時,結果的位就被設置為1;只有當兩個位的值都為0時,結果中的位才被設置為0。
c)【^】位異或運算,從兩個表達式中取得對應的位。如果輸入表達式中兩個痊只有一個的值為1時,結果中的位就被設置為1;只有當兩個位的值都為0或1時,結果中的位才被設置為。
3)比較運算符
=、<>、 >、!=、<、!<、>=、!>、<=
4)邏輯運算符
a)【ALL】如果一組的比較都為TRUE,則比較結果為TRUE。
b)【AND】如果兩個布爾表達式都為TRUE,則結果為TRUE;如果其中一個表達式為FALSE,則結果為FALSE。
c)【ANY】如果一組的比較中任何一個為TRUE,則結果為TRUE。
d)【BETWEEN】如果操作數(shù)在某個范圍之內(nèi),那么結果為TRUE。
e)【EXISTS】如果子查詢中包含了一些行,那么結果為TRUE。
f)【IN】如果操作數(shù)據(jù)等于表達式列表中的一個,那么結果為TRUE。
g)【LIKE】如果操作數(shù)據(jù)與某種模式相匹配,那么結果為TRUE。
h)【NOT】對任何其他布爾運算符的結果值取反。
i)【OR】如果兩個布爾表達式中的任何一個為TRUE,那么結果為TRUE。
j)【SOME】如果在一組比較中,有些比較為TRUE,那么結果為TRUE。
5)其他運算符
a)賦值運算符
b)連接運算符
c)一元運算符
1.【+】數(shù)值為正
2.【-】數(shù)值為負
3.【~】返回數(shù)字的邏輯非
?
4、表達式
?
DECLARE?@STR?NVARCHAR(50)SELECT?@STR?=?'用戶名:'?+?UserName?+?'?密碼:'+?Password?FROM?[User]?where?UserId=196
SELECT?@STR?as?Info
?
5、T-SQL語句中的注釋
?
注釋
1)注釋是程序代碼中不被執(zhí)行的文本字符串,用于對代碼進行說明或暫時用來進行診斷的部分語句。一般地,注釋主要描述程序名稱、作者名稱、變量說明、代碼更改日期、算法描述等。
?
2)在Microsoft SQL Server 2008系統(tǒng)中,支持兩種注釋方式,即雙連字符(--)注釋方式和正斜杠星號字符(/*...*/)注釋方式
?
DECLARE?@UserName?Nvarchar(20)?--用戶名稱DECLARE?@Password?Nvarchar(32)?--用戶密碼(MD5)
DECLARE?@Result?Bit?--是否存在
SET?@UserName='agent'
SET?@Password='30B8CA8354B5AC6542797BFF9623B346'
/*
????METHOD:驗證指定用戶信息的數(shù)據(jù)是否存在
????NOTE:用戶登錄
????DATE:2013-08-21?13:35????
*/
if?exists(SELECT?*?FROM?[User]?where?UserName=@UserName?and?Password=@Password)
????SELECT?1?AS?Result
else
????SELECT?0?AS?Result
?
6、BEGIN...END語句
?
語法格式
BEGIN
{
sql_statement | statement_block
}
END
?
declare?@userName?nvarchar(20)if?@userName?is?not?null
????BEGIN
????????select?*?from?[User]?where?userName=@userName
????????print?'查詢成功'
????END
else
????print?'查詢失敗,userName?參數(shù)不能為空'
?
7、IF..ELSE語句
?
語法格式
IF Boolean_expression
{sql_statement|statement_block}
ELSE
{sql_statement|statement_block}
?
declare?@num?decimal(18,2)select?@num?=?SUM(Amount)?from?ProfitLoss?WHERE?UserId=196
if?@num>10000.00
????--BEGIN
????????print?'重要會員'
????--END
else
????--BEGIN
????????print?'普通會員'
????--END
?
8、IF...ESLE語句嵌套
?
declare?@num?decimal(18,2)select?@num?=?SUM(Amount)?from?ProfitLoss?WHERE?UserId=196
if?@num>5000.00
????BEGIN
????????IF?@num<6000.00
????????????print?'高級會員';
????????ELSE?IF?@num<7000.00????????
????????????print?'中級會員'
????????ELSE
????????????print?'重要會員';
????END
else
????--BEGIN
????????print?'普通會員';
????--END
?
9、Case 語句
?
語法格式
CASE input_expression
WHEN when_expression THEN result_expression
[,...n]
[ELSE else_result_expression]
END
?
10、Case 語句示例
?
SELECT?*,roleName=case?roleId
when?1?then?'管理員'
when?2?then?'代理'
when?3?then?'普通會員'
else?'未知角色'
end
from?[User]
?
11、While語句
?
語法格式
WHILE Boolean_expression
{sql_statement|statement_block}
[BREAK]
{sql_statement|statement_block}
[CONTINUE]
{sql_statement|statement_block}
?
declare?@i?int
set?@i=0
while(@i<100)
Begin
????set?@i=@i+1
????print?@i
END
?
12、While語句示例(獲取指定欄目的所有下屬之欄目的編號)
?
SET?ANSI_NULLS?ONGO
SET?QUOTED_IDENTIFIER?ON
GO
--?=============================================
--?Author:????????<cxmsky@gmail.com>
--?Create?date:?<2013-08-21?15:41>
--?Description:????<獲取指定欄目下的所有子欄目>
--?=============================================
CREATE?FUNCTION?GetChild(@catId?int)
RETURNS?@t?TABLE(CatId?int,CatName?nvarchar(10),ParentId?int,Level?int)?
AS
BEGIN
????declare?@i?int
????set?@i?=?(SELECT?[Level]?from?Category?where?CatId=@catId)
????insert?into?@t?SELECT?CatId,CatName,ParentId,[Level]?from?Category?where?CatId=@catId
????while?@@rowcount>0
????BEGIN
????????set?@i?=?@i+1
????????insert?into?@t
????????SELECT?a.CatId,a.CatName,a.ParentId,a.[Level]
????????FROM?Category?a,@t?b
????????WHERE?a.ParentId=b.CatId?and?b.[Level]?=?@i-1
????END
????return
END
?
13、While語句中使用其他語句
?
--求3-100之間的所有質(zhì)數(shù)(素數(shù))--從小數(shù)學就不好
declare?@i?int
declare?@j?int
set?@i=3
while?@i<=100
begin
????declare?@bol?int
????set?@bol?=?1
????set?@j=2
????while?@j<=SQRT(@i)
????BEGIN
????????if?@i%@j?=?0
????????BEGIN
????????????set?@bol?=?0
????????????break
????????END
????????set?@j=@j+1
????END
????if?@bol?=?1?print?@i
????set?@i=@i+1
end
?
14、WAITFOR延遲語句
?
語法格式
WAITFOR
{
DELAY time | TIME time
}
?
--等待指定時間段執(zhí)行?sp_help?存儲過程waitfor?delay?'00:00:05'
exec?sp_help
--等待到指定時間執(zhí)行?sp_help?存儲過程
waitfor?time?'16:05:05'
exec?sp_help
select?GETDATE()
?
15、GOTO語句
?
DECLARE?@Counter?int;
SET?@Counter?=?1;
WHILE?@Counter?<?10
BEGIN?
????SELECT?@Counter
????SET?@Counter?=?@Counter?+?1
????IF?@Counter?=?4?GOTO?Branch_One?--Jumps?to?the?first?branch.
????IF?@Counter?=?5?GOTO?Branch_Two??--This?will?never?execute.
END
Branch_One:
????SELECT?'Jumping?To?Branch?One.'
????GOTO?Branch_Three;?--This?will?prevent?Branch_Two?from?executing.
Branch_Two:
????SELECT?'Jumping?To?Branch?Two.'
Branch_Three:
????SELECT?'Jumping?To?Branch?Three.'
?
16、TRY...CATCH錯誤處理語句
?
語法格式
BEGIN TRY
{sql_statement|statement_block}
END TRY
BEGIN CATCH
{sql_statement|statement_block}
?END CATCH
?
begin?try????declare?@num?int
????select?@num?=?(SELECT?UserName?from?[User]?where?UserId=196)
end?try
begin?catch
????select?ERROR_LINE()?as?'行數(shù)',ERROR_MESSAGE()?as?'消息'
end?catch
?
17、數(shù)學函數(shù)
?
1)【ABS】返回數(shù)值表達式的絕對值
2)【EXP】返回指定表達式以e為底的指數(shù)
3)【CEILING】返回大于或等于數(shù)值表達式的最小整數(shù)
4)【FLOOR】返回小于或等于數(shù)值表達式的最大整數(shù)
5)【LN】返回數(shù)值表達式的自然對數(shù)
6)【LOG】返回數(shù)值表達式以10為底的對
7)【POWER】返回對數(shù)值表達式進行冪運算的結果
8)【ROUND】返回舍入到指定長度或精度的數(shù)值表達式
9)【SIGN】返回數(shù)值表達式的正號(+)、負號(-)或零(0)
10)【SQUARE】返回數(shù)值表達式的平方
11)【SQRT】返回數(shù)值表達式的平方根
?
declare?@i?float,@j?int,@a?decimal(18,2)set?@i?=?-12.2344
set?@j?=?100
print?abs(@i)?--取絕對值
print?abs(round(@i,2))?--指定精度
print?floor(abs(round(@i,2)))?--返回小于或等于數(shù)值表達式的最大整數(shù)
print?ceiling(abs(round(@i,2)))?--?返回大于或等于數(shù)值表達式的最小整數(shù)
print?power(@j,0.5)?--返回對數(shù)值表達式進行冪運算的結果
print?square(@j)?--返回數(shù)值表達式的平方
print?sqrt(@j)?--返回數(shù)值表達式的平方根
?
18、字符串函數(shù)?
?
1)【ASCII】 ASCII函數(shù),返回字符表達式中最左側的字符的ASCII代碼值
2)【CHAR】ASCII代碼轉換函數(shù),返回指定ASCII代碼的字符
3)【LEFT】左子串函數(shù),返回字符串中從左邊開始指定個數(shù)的字符
4)【LEN】字符串函數(shù),返回指定字符串表達式的字符(而不是字節(jié))數(shù),其中不包含尾隨空格
5)【LOWER】小寫字母函數(shù),將大寫字符數(shù)據(jù)轉換為小寫字符數(shù)據(jù)后返回字符表達式
6)【LTRIM】刪除前導空格字符串,返回刪除了前導空格之后的字符表達式
7)【REPLACE】替換函數(shù),用第三個表達式替換第一個字符串表達式中出現(xiàn)的所有第二個指定字符串表達式的匹配項
8)【REPLICATE】復制函數(shù),以指定的次數(shù)重復字符表達式
9)【RIGHT】右子串函數(shù),返回字符串中從右邊開始指定個數(shù)的字符
10)【RTRIM】刪除尾隨空格函數(shù),刪除所有尾隨空格后返回一個字符串
11)【SPACE】空格函數(shù),返回由重復的空格組成的字符串
12)【STR】數(shù)字向字符轉換函數(shù),返回由數(shù)字數(shù)據(jù)轉換來的字符數(shù)據(jù)
13)【SUBSTRING】子串函數(shù),返回字符表達式、二進制表達式、文本表達式或圖像表達式的一部分
14)【UPPER】大寫函數(shù),返回小寫字符數(shù)據(jù)轉換為大寫的字符表達式
15)【CHARINDEX】返回字符串中某個指定的子串出現(xiàn)的開始位置
CHARINDEX(<'substring_expression'>,<expression>)
其中substring_expression是所要查找的字符表達式,expression可為字符串也可為列名表達式。如果沒有發(fā)現(xiàn)子串,則返回0值。
此函數(shù)不能用于TEXT和IMAGE數(shù)據(jù)類型。
16)【PATINDEX】返回字符中某個指定的子串出現(xiàn)的開始位置。
PATINDEX(<'%substring_expression%'>,<column_name>)其中子串表達式前后必須有百分號“%”,否則返回值為0。
與CHARINDEX函數(shù)不同的是,PATINDEX函數(shù)的子串中可以使用通配符,且此函數(shù)可用于CHAR、VARCHART和TEXT數(shù)據(jù)類型。
?
19、字符串函數(shù)示例
?
declare?@str1?nvarchar(20)declare?@str2?nvarchar(20)
declare?@str3?nvarchar(20)
declare?@str4?nvarchar(20)
declare?@str5?nvarchar(20)
set?@str1?=?'北京分公司經(jīng)理'
set?@str2?=?'天津分公司經(jīng)理'
set?@str3?=?'上海分公司經(jīng)理'
set?@str4?=?'北京分公司財務經(jīng)理'
set?@str5?=?'上海分公司財務經(jīng)理'
print?RIGHT(@str5,LEN(@str5)?-?CHARINDEX('分公司',@str5)?+?1)
?
?20、聚合函數(shù)
?
1)AVG 獲取平均值
2)COUNT 獲取數(shù)量
3)MAX 獲取最大值
4)MIN 獲取最小值
5)SUM 獲取和值
?
21、日期和時間函數(shù)
?
1)DATEADD 返回給指定日期加上一個時間間隔后的新的DateTime值。
2)DATEDIFF 返回跨兩個指定日期的日期邊界數(shù)和時間邊界數(shù)。
3)DATENAME 返回表示指定日期的指定日期部分的字符串。
4)DATEPART 返回表示指定日期的指定日期部分的整數(shù)。
5)DAY 返回一個整數(shù),表示指定日期的天DATEPART部分。
6)GETDATE 以DateTime值的SQL SERVER 2008標準內(nèi)部格式返回當前系統(tǒng)日期和時間。
7)GETUTCDATE 返回表示當前的UTC時間(通用協(xié)調(diào)時間或格林尼治標準時間)的DateTime值。當前的UTC時間得自當前的本地時間和運行Microsoft Sql Server 2008實例的計算機操作系統(tǒng)中的時區(qū)設置。
8)MONTH 返回表示指定日期的“月”部分的整數(shù)。
9)YEAR 返回表示指定日期的年份的整數(shù)。
?
declare?@date?DateTimeset?@date?=?GETDATE()
--set?@date?=?GETUTCDATE()
SELECT?@date,YEAR(@date)?as?年份,MONTH(@date)?as?月份,DAY(@date)?as?日,DATEPART(year,@date)?as?年份,DATEPART(MONTH,@date)?as?月份,?DATEPART(DAY,@date)?as?日,?DATEPART(HH,@date)?as?小時,DATEPART(MM,@date)?as?分鐘,DATEPART(SS,@date)?as?秒鐘,DATEADD(dd,1,@date)?as?明天此時
?
22、標量值函數(shù)
?
語法格式:
CREATE FUNCTION function_name
([{@parameter_name scalar_parameter_data_type[=default]}[,...n]])
RETURNS scalar_return date_type
[WITH ENCRYPTION]
[AS]
BEGIN
function_body
RETURN scalar_expression
END
?
--獲取指定用戶的平均消費數(shù)據(jù)CREATE?FUNCTION?GETSUMAmount(@userId?int)
Returns?decimal(18,2)
AS
BEGIN
????declare?@result?decimal(18,2)
????SELECT?@result?=?SUM(Amount)?from?Profitloss?where?UserId=@userId
????return?@result
END
GO
SELECT?[dbo].GETSUMAmount(197)
?
23、表值函數(shù)
?
語法格式:?
CREATE FUNCTION function_name
([{@parameter_name scalar_parameter_data_type [=default]}[,...n]])
RETURNS TABLE
[WITH ENCRYPTION]
[AS]
RETURN (select_statement)
?
CREATE?FUNCTION?GETALLPLAYTYPE(@lotteryId?int)RETURNS?TABLE
AS
RETURN
(
????select?a.LotteryName,b.ModeName,c.*?
????from
????Lottery?a,PlayMode?b,PlayType?c????
????where?c.lotteryId?=?@lotteryId?and?c.lotteryId?=?a.lotteryId?and?c.modeId?=?b.modeId
)
GO
select?*?from?GETALLPLAYTYPE(1)
?
24、系統(tǒng)與元數(shù)據(jù)函數(shù)
?
1)CONVERT() 將一種數(shù)據(jù)類型的數(shù)據(jù)轉變?yōu)榱硪环N數(shù)據(jù)類型的數(shù)據(jù)
2)CURRENT_USER 返回當前用戶的名稱
3)ISDATE() 判斷它的輸入是不是一個有效的日期
4)ISNULL() 用一個指定替換值替換任何空值
5)ISNUMERIC() 判斷它的輸入是不是一個數(shù)值。
?
declare?@str?varchar(10),@i?int,@j?intset?@str?=?'12'
set?@i?=?10
if?ISNUMERIC(@str)?=?1
begin
????print?convert(int,@str)?*?@i
end
print?ISNULL(@j,10)?*@i
?
25、事務
?
在SQL Server 2008系統(tǒng)中主要使用下列4條語句管理事務:
1)BEGIN TRANSACTION
2)COMMIT TRANSACTION
3)ROLLBACK TRANSACTION
4)SAVE TRANSACTION
?
26、SQL Server 2008 事務模式
?
事務模式
1)自動提交事務
每條單獨的語句都是一個事務(默認,如Insert / update / delete / select)
2)顯示事務
每個事務均以BEGIN TRANSACTION語句顯式開始,以COMMIT或ROLLBACK語句顯式結束
3)隱式事務
在前一個事務完成時新事務隱式啟動,但每個事務仍以COMMIT或ROLLBACK語句顯示完成。如:觸發(fā)器
4)批處理級事務
只能應用于多個活動結果集(MARS),在MARS會話中啟動的Transact-SQL顯式或隱式事務變?yōu)榕幚砑壥聞铡.斉幚硗瓿蓵r沒有提交或回滾的批處理級事務自動由SQL Server進行回滾。
?
27、XACT_ABORT選項
?
XACT_ABORT選項
1)XACT_ABORT選項用于指定當SQL語句出現(xiàn)運行時錯誤時,SQL Server是否自動回滾到當前事務。其語法格式如下所示:
SET XACT_ABORT {ON|OFF}
2)當SET XACT_ABORT為ON時,如果執(zhí)行SQL語句產(chǎn)生運行時錯誤,則整個事務將終止并回滾。當SET XACT_ABORT為OFF時,有時只回滾產(chǎn)生錯誤的SQL語句,而事務將繼續(xù)進行處理。如果錯誤很嚴重,那么即使SET XACT_ABORT為OFF,也可能回滾整個事務。
3)SET XACT_ABORT的設置是執(zhí)行或運行時設置,而不是分析時設置。對于大多數(shù)OLEDB提供程序,必須將隱式或顯示事務中的數(shù)據(jù)修改語句中的XACT_ABORT設置為ON。唯一不需要該選項的情況是在提供程序支持嵌套事務時。
?
28、嵌套事務 (略)
?
29、鎖
?
概述
所謂封鎖,就是一個事務可向系統(tǒng)提出請求,對被操作的數(shù)據(jù)加鎖(Lock)。其他事務必須等到此事務解鎖(Unlock)之后才能訪問該數(shù)據(jù)。從而,在多個用戶并發(fā)訪問數(shù)據(jù)庫時,確保不互相干擾。可鎖的單位是:行、頁、表、盤區(qū)和數(shù)據(jù)庫。
?
鎖的類型
?
1)共享(S)鎖:用于讀操作。
多個事務可封鎖一個共享單位的數(shù)據(jù)。任何事務都不能修改加S鎖的數(shù)據(jù)。通常是加S鎖的數(shù)據(jù)被讀取完畢,S鎖立即被釋放。
2)獨占(X)鎖:用于寫操作。
僅允許一個事務封鎖此共享數(shù)據(jù)。其他任何事務必須等到X鎖被釋放才能對該數(shù)據(jù)進行訪問。X鎖一直到事務結束才能被釋放。
3)更新(U)鎖
用來預定要對此頁施加X鎖,它允許其他事務讀,但不允許再施加U鎖或鎖。當被讀取數(shù)據(jù)頁將要被更新時,則升級為X鎖。U鎖一直到事務結束才能被釋放。
?
30、死鎖
?
死鎖
1)所謂死鎖是指兩個或兩個以上的進程在執(zhí)行過程中,因爭奪資源而造成的一種互相等待的現(xiàn)象,若無外力作用,它們都將無法推進下去,此時稱系統(tǒng)處于死鎖狀態(tài)或系統(tǒng)產(chǎn)生了死鎖,這些永遠在互相等待的進程稱為死鎖進程。
2)由于資源占用是互斥的,當某個進程提出申請資源后,使得有關進程在無外力協(xié)助下,永遠分配不到必需的資源而無法繼續(xù)運行,這就產(chǎn)生了一種特殊現(xiàn)象:死鎖。
3)一種情形,此時執(zhí)行程序中兩個或多個線程發(fā)生永久堵塞(等待),每個線程都在等待被其他線程占用并堵塞了的資源,例如,如果線程A鎖住了記錄1,并等待記錄2,而線程B鎖住了記錄2并等待記錄1,這樣兩個線程就發(fā)生了死鎖現(xiàn)象。
?
必要條件:
1)互斥條件:一個資源每次只能被一個進程使用
2)請求與保持條件;一個進程因請求資源而阻塞時,對已獲得的資源保持不放。
3)不剝奪條件:進程已經(jīng)獲得的資源,在未使用完之前,不能強制剝奪。
4)循環(huán)等待條件:若干線程之間形成一種頭尾相接循環(huán)等待資源關系。
?
這四個條件是死鎖的必要條件,只要系統(tǒng)發(fā)生死鎖, 這些條件必須成立,而只要上述條件之一不滿足,就不會發(fā)生死鎖。
?
死鎖的解除和預防
1)按同一順序訪問對象
2)避免事務中的用戶交互
3)保持事務的簡短性并在一個批處理中
4)使用低隔離級別
5)使用綁定連接
?
死鎖的建議
1)對于頻繁使用的表使用集簇化的索引。
2)設法避免一次性影響大量記錄的T-SQL語句,特別是INSERT和UPDATE語句。
3)設法讓UPDTAE和DELETE語句使用索引
4)使用嵌套事務時,避免提交和回退沖突
5)對一些數(shù)據(jù)不需要及時讀取更新值的表在寫SQL的時候在表名稱后面加上(nolock) ,如:Select * from T1(nolock)
?
31、游標概述
?
1)游標(Cursor)是一種數(shù)據(jù)訪問機制,它允許用戶訪問單獨的數(shù)據(jù)行,而不是對整個行集進行操作。用戶可以通過單獨處理每一行逐條收集信息并對數(shù)據(jù)逐行進行操作,這樣可以降低系統(tǒng)開銷和潛在的阻隔情況。用戶也可以使用這些數(shù)據(jù)生成SQL代碼并立即執(zhí)行或輸出。
?
2)游標主要包括以下兩部分:
a)游標結果集:由定義游標的SELECT語句返回的行的集合。
b)游標位置:指向這個結果集中的某一行的指針。
?
游標的特點
1)游標返回一個完整的結果集,但允許程序設計語言只調(diào)用集合中的一行。
2)允許定位在結果集的特定行。
3)從結果集的當前位置檢索一行或多行。
4)支持對結果集中當前位置的行進行數(shù)據(jù)修改。
5)可以為其他用戶對顯示在結果集中的數(shù)據(jù)庫數(shù)據(jù)所做的更改提供不同級別的可見性支持。
5)提供腳本、存儲過程和觸發(fā)器中使用的訪問結果集中數(shù)據(jù)庫的T-SQL語句。
?
32、游標的聲明
?
語法格式
DECLARE cursor_name [INSENSITIVE][SCROLL] CURSOR
FOR select_statement
[OFR{READ ONLY|UPDATE[OF column_name[,...n]]}]
--聲明游標
declare?category_cursor?SCROLL?Cursor
For
SELECT?*?FROM?CATEGORY?
for?read?only?|?update
?
33、使用游標
?
1)打開游標:OPEN{{[GLOBAL] cursor_name}|cursor_variable_name}
2)檢索游標:
FETCH
[NEXT|PRIOR|FIRST|LAST|ABSOLUTE{n|@nvar}|RELATIVE{n|@nvar}]
FORM ]
{{[GOBAL] cursor_name}|@cursor_variable_name}
[INTO @variable_name[,...n]]
3)關閉游標:CLOSE{{[GLOBAL] cursor_name}|cursor_variable_name}
4)釋放游標:DEALLOCATE{{[GLOBAL] cursor_name}|@cursor_variable_name}
?
--聲明游標declare?category_cursor?SCROLL?Cursor
For
SELECT?CatName?FROM?CATEGORY?
for?read?only
declare?@CatName?nvarchar(20)
--打開游標
--OPEN?category_cursor
FETCH?(NEXT|FIRST|PRIOR|LAST|ABSOLUTE?5)?from?category_cursor?INTO?@CatName
Print?@CatName
--關閉游標
CLOSE?category_cursor
--釋放游標
DEALLOCATE?category_cursor
?
34、判斷游標提取狀態(tài)
?
@@FETCH_STATUS
取值:
1)0 FETCH語句成功
2)-1 FETCH語句失敗或行不在結果集中
3)-2 提取的行不存在
?
if?@@FETCH_STATUS?=?0Print?'數(shù)據(jù)提取成功'
else?if?@@FETCH_STATUS?=?-1
Print?'語句失敗或行不在結果集中'
else?if?@@FETCH_STATUS?=?-2
Print?'提取的行不存在'
?
35、游標應用示例(略)
?
--游標使用示例--聲明游標
DECLARE?stu_cursor?scroll?cursor?for?select?學號?from?學生信息
--創(chuàng)建臨時表
create?table?#t(name?nvarchar(20),sorce?int)
--打開游標
open?stu_cursor
--定義一個變量用于存儲查詢到的學號
DECLARE?@NAME?varhcar(20)
--讀取下一條記錄,并把結果存儲到已聲明的@NAME變量中
FETCH?next?from?stu_cursor?INTO?@NAME
--判斷全局變量(游標狀態(tài))
while?@@FETCH_STATUS?=?0
BEGIN
--把查詢到的記錄插入到臨時表中
insert?into?#t?
select?B.姓名,AVG(分數(shù))?as?分數(shù)?FROM?成績信息?A?JOIN?學生信息?B?ON?A.學生編號=B.學號?
where?A.考試編號='0801'?AND?B.學號=@NAME?
GROUP?BY?B.姓名
FETCH?next?FROM??stu_cursor
INTO?@NAME
END
--關閉游標
CLOSE?stu_cursor
--釋放游標
DEALLOCATE?stu_cursor
?
?
?
轉載于:https://www.cnblogs.com/cxmsky/p/3272478.html
總結
以上是生活随笔為你收集整理的SQL_Server_2008完全学习之第八章Transact-SQL编程的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Apple 预计于内华达州雷诺市再盖一个
- 下一篇: 关于织梦系统不支持php中GD库的问题