理解T-SQL: 脚本和批处理
????? 腳本能夠?qū)⑾鄳?yīng)的T-SQL命令組織起來,實(shí)現(xiàn)一個完整的功能目標(biāo)。腳本提供了變量、分支、循環(huán)等控制語句,可以用來實(shí)現(xiàn)一些復(fù)雜的任務(wù)。通過組織一系列的SQL命令編成腳本和批處理,也減低了數(shù)據(jù)庫管理的復(fù)雜性。
1. USE語句
???? 沒啥好講的,功能就是設(shè)置當(dāng)前的數(shù)據(jù)庫。
2. 聲明變量
???? 使用declare關(guān)鍵字,語法非常簡單:
?????? declare @<變量名> <變量類型> [,@<變量名> <變量類型> [.. ]]
??? 可以一次聲明多個變量。變量聲明后,但未賦值前,其值為NULL。
3. 給變量賦值
???? 有兩種方法,使用SET和使用select.
??? 當(dāng)知識該值是確切值或者是其它變量時,使用SET、當(dāng)變量賦值基于一個查詢時,使用SELECT
?????select?@Test=Max(Unitprice)?from?SalesOrderDetail;
4. 系統(tǒng)變量
????? SQL Server有30多個全局系統(tǒng)變量,但以下幾個關(guān)鍵的系統(tǒng)變量要記住,經(jīng)常用到:
???? @@ERROR??????????????? :??? 返回當(dāng)前連接下,最后執(zhí)行T-SQL語句的錯誤代碼,如無錯誤則返回0
???? @@FETCH_STATUS?? :???? 和FETCH配合使用,返回0表示FETCH有效,%表示超出結(jié)果集,-2表示不存在該行
???? @@IDENTITY??????????? :???? 返回最后插入的標(biāo)識值,作為最后INSERT或者SELECT INTO語句的結(jié)果。
???? @@ROWCOUNT??????? :???? 一個最有用的系統(tǒng)變量,返回最后語句影響的函數(shù)
???? @@SERVRNAME??????? :??? 返回腳本正在運(yùn)行的本地服務(wù)器的名字
???? @@TRANCOUNT??????? :??? 返回活動事務(wù)的數(shù)量。
?
5.批處理
???? 批處理是T-SQL語句集合的邏輯單元。 在批處理的所有語句被整合成一個執(zhí)行計劃。一個批處理內(nèi)的所有語句要么被放在一起通過解析,要么沒有一句能夠執(zhí)行。
??? 為了將腳本分成多個批處理,需要使用GO語句.以下語句被分為三個批處理:
DECLARE?@MyVarchar?varchar(50)?--This?DECLARE?only?lasts?for?this?batch!
SELECT?@MyVarchar?=?‘Honey,?I’’m?home’
PRINT?‘Done?with?first?Batch’
GO
PRINT?@MyVarchar?--This?generates?an?error?since?@MyVarchar???--isn’t?declared?in?this?batch
PRINT?‘Done?with?second?Batch’
GO
PRINT?‘Done?with?third?batch’?--?Notice?that?this?still?gets?executed?--?even?after?the?error
GO
?
???? 對于以上,每一個批處理都會被獨(dú)立執(zhí)行,每個批處理的錯誤不會阻止其它批處理的運(yùn)行(批處理2發(fā)生錯誤,不被執(zhí)行,但批處理3照樣可以執(zhí)行。)
???? 另外,GO不是一個SQL命令,它只是一個被編輯工具(SQL Server Management Studio,SQLCMD)識別的命令。
?
6.何時使用批處理
????? 批處理有多種用途,但常被用在某些事情不得不放在前面發(fā)生,或者不得不和其它事情分開的腳本中。
???? 使用以下幾個命令時,必須獨(dú)自成批處理,包括:
???? ● CREATE DEFAULT
???? ● CREATE PROCEDURE
???? ● CREATE RULE
???? ● CREATE TRIGGER
???? ● CREATE VIEW
?
7. 使用批處理建立優(yōu)先級
????? 當(dāng)需要考慮語句執(zhí)行的優(yōu)先順序時,需要一個任務(wù)在另一個任務(wù)開始前,前一個任務(wù)必須被執(zhí)行。優(yōu)先級就需要考慮到。看一下下面的例子:??
CREATE?DATABASE?TestUSE?Test
CREATE?TABLE?TestTable
(
col1?int,
col2?int
)
???? 以上語句不能正確執(zhí)行,原因何在,是因?yàn)樵赨SE Test時,必須需要前面一條語句"Create DataBase Test”被執(zhí)行,而要讓創(chuàng)建數(shù)據(jù)庫的命令在USE TEST時被執(zhí)行,必須為前面一個語句創(chuàng)建批處理:
GO
USE?Test
CREATE?TABLE?TestTable
(
????col1?int,
????col2?int
)
??? 然后,用以下語句進(jìn)行驗(yàn)證,發(fā)現(xiàn)表確實(shí)被創(chuàng)建了:
SELECT?TABLE_CATALOG?FROM?INFORMATION_SCHEMA.TABLES?WHERE?TABLE_NAME?=?‘TestTable’;
?
8. 創(chuàng)建批處理后的執(zhí)行
???? ●可以使用sqlcmd命令來執(zhí)行,一般命令格式如下:
????? c:\>sqlcmd –Usa –Ppasswd –i mysql.sql
??? sqlcmd的命令開關(guān)包括很多項,以下列出:
[?{?{?-U?<login?id>?[?-P?<password>?]?}?|?–E?<可信連接>}?]
[-S?<服務(wù)器名>?[?\<實(shí)例名>?]?]?[?-H?<工作站名>?]?[?-d?<數(shù)據(jù)庫名>?]
[?-l?<登錄超時>?]?[?-t?<查詢超時>?]?[?-h?<標(biāo)題(間行數(shù))>?]
[?-s?<列分隔符>?]?[?-w?<列寬>?]?[?-a?<分組大小>?]
[?-e?]?[?-I?]
[?-c?<批處理終止符>?]?[?-L?[?c?]?]?[?-q?“<query>”?]?[?-Q?“<query>”?]
[?-m?<error?level>?]?[?-V?]?[?-W?]?[?-u?]?[?-r?[?0?|?1?]?]
[?-i?<input?file>?]?[?-o?<output?file>?]
[?-f?<代碼頁>?|?i:<輸入代碼頁>?[?<,?o:?<輸出代碼頁>?]
[?-k?[?1?|?2?]?]
[?-y?<可變類型顯示寬度>?]?[-Y?<固定類型顯示寬度>?]
[?-p?[?1?]?]?[?-R?]?[?-b?]?[?-v?]?[?-A?]?[?-X?[?1?]?]?[?-x?]
[?-??]
]
?? ● 另外,也可心使用EXEC來執(zhí)行相應(yīng)的批處理
????????? EXEC ((字符串變量)|(字面值命令字符串))
????????? EXECUTE ((字符串變量)|(字面值命令字符串))
DECLARE?@OutVar?varchar(50)
--?Set?up?our?string?to?feed?into?the?EXEC?command
SET?@InVar?=?‘SELECT?@OutVar?=?FirstName?FROM?Person.Contact?WHERE?ContactID?=?1’
EXEC?(@Invar)
??? 執(zhí)行EXEC有許多需要留意的地方,具體可查看《SQL Server2005高級程序設(shè)計》10.4節(jié)。
9. 流控制語句
???? T-SQL包括的流控制語句包括:
?????? ● IF…ELSE
?????? ● GOTO
?????? ● WHILE
?????? ● WAITFOR
?????? ● TRY/CATCH
?????? ● CASE
??? a. IF…ELSE語句
?????? IF…ELSE語句用得很頻繁,其基本語法是:
<SQL?statement>?|?BEGIN?<code?series>?END
[ELSE
<SQL?statement>?|?BEGIN?<code?series>?END]
?????? 注意,使用代碼行時,別忘了BEGIN與END
?????? 另外,對于IF判斷有一個陷阱,就是 if @var = NULL.這樣子寫法是不對的,因?yàn)镹ULL不等于任何東西,甚至也不等于NULL,應(yīng)該寫成:
???????? if @var IS NULL
???? b. CASE語句
???????? 有不止一句方式來寫CASE語句,可以同時輸入表達(dá)式或布爾表達(dá)式協(xié)同工作。
???????? 第一種選擇是使用一個輸入表達(dá)式,同每一個WHEN子句使用的值進(jìn)行比較,這種CASE稱作簡單CASE:?
WHEN?<when?expression>?THEN?<result?expression>
[n]
[ELSE?<result?expression>]
END
???????? 第二種情況是把每一個WHEN子句的布爾值提供給表達(dá)式,這種CASE叫作搜索CASE:
WHEN?<Boolean?expression>?THEN?<result?expression>
[n]
[ELSE?<result?expression>]
END
??????? ●● 簡單CASE需要使用一個能得到布爾值的表達(dá)式,例如:
CASE?SalesOrderID?%?10
????WHEN?1?THEN?‘First’
????WHEN?2?THEN?‘Second’
????WHEN?3?THEN?‘Third’
????WHEN?4?THEN?‘Fourth’
ELSE??‘Something?Else’
END
FROM?Sales.SalesOrderHeader
以上,得出的結(jié)果如下所示:
OrderID????? Last Digit??????? Position
---------??? -----------???? --------------------
10249?????????? 9????????????? Something Else
10251?????????? 1?????????????? First
10258?????????? 8?????????????? Something Else
10260?????????? 0?????????????? Something Else
10265?????????? 5?????????????? Something Else
10267?????????? 7?????????????? Something Else
10269?????????? 9?????????????? Something Else
10270?????????? 0?????????????? Something Else
10274?????????? 4?????????????? Fourth
10275?????????? 5?????????????? Something Else
(10 row(s) affected)
、? ●● 搜索CASE和簡單CASE類似,但有兩點(diǎn)微小的差異:
???????? 在CASE和第一個WHEN之間沒有輸入表達(dá)式
???????? WHEN表達(dá)式必須同一個布爾值相比較?
ProductID?%?10?AS?‘ProductLastDigit’,
“How?Close?”?=?
CASE
?????WHEN?(SalesOrderID?%?10)?<?3?THEN?‘Ends?With?Less?Than?Three’
?????WHEN?ProductID?=?6?THEN?‘ProductID?is?6’
?????WHEN?ABS(SalesOrderID?%?10?-?ProductID)?<=?1?THEN?‘Within?1’
ELSE
???‘More?Than?One?Apart’
END
FROM?Sales.SalesOrderDetail
???????? 得到的結(jié)果如下所示:
OrderLastDigit?????? ProductLastDigit?????? How Close?
--------------?????? ----------------?????? -------------------
2?????????????????????????????? 5?????????????????? More Than One Apart
3?????????????????????????????? 2?????????????????? More Than One Apart
3????????????????????????????? 9?????????????????? More Than One Apart
3?????????????????????????????? 8?????????????????? More Than One Apart
2?????????????????????????????? 2?????????????????? More Than One Apart
2????????????????????????????? 8????????????????? More Than One Apart
1????????????????????????????? 7?????????????????? Within 1
1?????????????????????????????? 0????????????????? Within 1
1????????????????????????????? 1?????????????????? Within 1
0????????????????????????????? 2????????????????? Exact Match!
??????? 搜索CASE把條件放到了WHEN后面,而不是所有的WHEN共用一個條件!
????
??? C. WHILE語句
??????????? WHILE語句的語法如下所示:
[BEGIN
?????<statement?block>
?????[BREAK]
??????<sql?statement>?|?<statement?block>
?????[CONTINUE]
END]
????????? 看一個例子,使用WHILE與WAITFOR創(chuàng)建一個監(jiān)視進(jìn)程 ,打算每天自動更新一次統(tǒng)計數(shù)據(jù):
BEGIN
???????WAITFOR?TIME?‘01:00’
???????EXEC?sp_updatestats
???????RAISERROR(‘Statistics?Updated?for?Database’,?1,?1)?WITH?LOG
END
?????? d. WAITFOR語句
?????????? WAITFOR語句表示時間等待,語法如下:
WAITFOR
?????? DELAY <’time’> | TIME <’time’>
?????????? DELAY參數(shù)指定等待的時間量,不能指定天數(shù),只能指定小時,分鐘,秒。最大的延遲時間是24小時,
?????????? TIME參數(shù)指定等到一天中某個特定時刻。同樣也只能用24小時制:?
轉(zhuǎn)載于:https://www.cnblogs.com/shipfi/archive/2009/10/14/1582899.html
總結(jié)
以上是生活随笔為你收集整理的理解T-SQL: 脚本和批处理的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 失业日志:2009年10月12日星期一
- 下一篇: SQL进阶提升(疑惑篇order by)