SQL SERVER7应用
生活随笔
收集整理的這篇文章主要介紹了
SQL SERVER7应用
小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
交互式SQL(Transact SQL,TSQL)
它是SQL Server的查詢語言。提供以下命令:
· 創(chuàng)建和數(shù)據(jù)庫對象。
· 訪問和修改數(shù)據(jù)。
· 數(shù)據(jù)聚合(aggregation,又稱聚集)。
· 實施安全措施。
數(shù)據(jù)庫對象
???????數(shù)據(jù)庫對象是數(shù)據(jù)庫中的物理對象。這些對象擁有唯一的名字,并保存數(shù)據(jù)和數(shù)據(jù)關(guān)系信息。SQL Server定義了如下幾種對象:
1、 表(table)
表是用來存儲數(shù)據(jù)的兩維數(shù)組,它有行和列。列也稱為表屬性或字段,表中的每一列擁有唯一的名字,每一列包含具體的數(shù)據(jù)類型,這個數(shù)據(jù)類型由列中的數(shù)據(jù)類型定義。
2、 視圖(view)
視圖是虛擬的表,它只包含表的一部分。與表不同的是,保存在視圖中的數(shù)據(jù)并不是物理存儲的數(shù)據(jù),它是由表派生的,派生表被稱為視圖的基本表。視圖的定義存儲在數(shù)據(jù)庫中。
3、 約束條件(constraint)
約束條件定義數(shù)據(jù)的完整性和有效性。約束條件為列中的值建立規(guī)則。換而言之,如果在某一列上定義了結(jié)束條件,則插入這一列的每一個值需要通過約束條件檢查。約束條件是在觸發(fā)器和規(guī)則上保證數(shù)據(jù)完整性和有效性的較佳選擇。SQL Server Query Optimizer利用約束條件產(chǎn)生出低成本的查詢計劃。約束條件有如下類型:
· NOT NULL 這個約束條件要求列中不能有NULL值。
· CHECK 為列指定能擁有的值的集合后,檢查約束條件。列中任何在定義之外的數(shù)據(jù)都為無效數(shù)據(jù)。有效值集合稱為列的域。
· PRIMARY KEY 主關(guān)鍵字是列或列組合,它用來唯一標識一行。
· FOREIGN KEY 用來定義兩個表之間的父子關(guān)系。如果一個關(guān)鍵字既是一個表的主關(guān)鍵字的一部分,同時又是另一個表的主關(guān)鍵字,則稱它為外來關(guān)鍵字。外來關(guān)鍵字用來定義數(shù)據(jù)的引用完整性。
· UNIQUE 唯一約束條件是指無任何兩行在列中有相同的NON-NULL值。唯一性由主關(guān)鍵字保證,但他們不允許NULL值,并且每一個表只能有一個關(guān)鍵字。
4、 默認值(default)
默認值是為列定義的值,如果在插入一行時沒有提供某一列的值,則此列使用默認值,默認值可以是以下的一種:
· 常量
· 數(shù)學表達式
· 內(nèi)部函數(shù)(Built-in function)
5、 規(guī)則(rule)
規(guī)則執(zhí)行和CHECK約束條件同樣的功能。但規(guī)則和約束條件不同的是:規(guī)則作為獨立的對象存在,它可以用于多個表,而約束條件作為表的一部分存儲。然而,規(guī)則是作為向后兼容特點而提供的,建議用戶使用約束條件。
6、 觸發(fā)器和存儲過程
觸發(fā)器和存儲過程是一個TSQL命令集,它們作為一個對象存儲在數(shù)據(jù)庫中。
對象命名約定
SQL Server用三段式(three-part)名字標識對象:
<數(shù)據(jù)庫名>.<所有者名>.<對象名>
前兩部分可以省略,系統(tǒng)有一個默認值。數(shù)據(jù)庫名的默認值是當前數(shù)據(jù)庫,所有者名的默認值是數(shù)據(jù)庫所有者(dbo)。
數(shù)據(jù)類型
???????任何包含數(shù)據(jù)的對象都有一個數(shù)據(jù)類型和它關(guān)聯(lián)。數(shù)據(jù)類型是指定對象能包含何種數(shù)據(jù)的屬性。
???????SQL Server數(shù)據(jù)類型
數(shù)據(jù)類型
說??明
同??義
Bit
1位,值為0或1
Int
Integer
4字節(jié),值為-2^31~2^31-1
Smallint
2字節(jié),值為-2^15~2^15-1
Tinyint
1字節(jié),值為0~255
Decimal (p,s)
數(shù)字數(shù)據(jù),固定精度為P,寬度為S
Numeric
Money
8字節(jié),存放貨幣類型,值為-2^63~2^63-1
Small money
4字節(jié),存放貨幣類型,值為-214748.3648~+214748.3647近似數(shù)值數(shù)據(jù)類型
Float (n)
N在1~24之間,4字節(jié),7位精度
N=1~7為real
N在25~53之間,8字節(jié),15位精度
=8~15為float
Datetime
8字節(jié),描述某天的日期和時刻,值的精確度為1/300秒
Smalldatetime
4字節(jié),描述某天的日期和時刻,精度為分鐘
Cursor
對游標的引用
Timestamp
8字節(jié),存放在數(shù)據(jù)庫內(nèi)唯一的數(shù)據(jù)
Uniqueidentifier
16字節(jié),存放全局唯一標識(GUID)
Char (n)
非unicode字符串的固定長度,n=1~8000
Character (n)
Varchar (n)
可變長度,非unicode字符串n=1~8000
Char varying(n)
Text
服務(wù)器代碼頁中可變長度非unicode數(shù)據(jù)。最大長度為231-1個字符
Nchar
固定長度unicode字符串n=1~4000
National character (n),
National char(n)
Nvarchar
固定長度unicode字符串n=1~4000
National character varying(n)
Ntext
可變長度unicode數(shù)據(jù),最大長度為230-1個字符
National text
Binary (n)
固定長度二進制數(shù)據(jù),n在1~8000之間,存儲空間為n+4字節(jié)
Varbinary (n)
可變長度二進制數(shù)據(jù),n=1~8000
Binary varying (n)
Tmage
可變長度二進制數(shù)據(jù),大小為0~231-1
注意:
1)????對于數(shù)值型數(shù)據(jù)類型,寬度(scale)是指存儲在小數(shù)點后的數(shù)字位數(shù),而精度(precision)是指能存儲的包含小數(shù)點在內(nèi)的所有數(shù)字位數(shù)。
2)????money和small money的存儲寬度為4。
3)????時間戳列值在每一行更新時系統(tǒng)自動更新,時間戳列不能是關(guān)鍵字或關(guān)鍵字的一部分。
4)????唯一標識數(shù)據(jù)類型不能使用算術(shù)操作符(如+、-等),這種數(shù)據(jù)類型只能使用相等比較操作。Unicode是所有字符集的一致存儲數(shù)據(jù)的標準。它要使用兩倍于非Unicode數(shù)據(jù)存儲的存儲空間。
存取數(shù)據(jù)
select語句
1. 選擇表中的所有列
“*”對Select語句有特殊意義。它指定表中的所有列,而不用列出列的名字。列的順序和表中的順序相同。
2. 選擇不同的值
如果被選擇列表中的列有重復值,這時“distinct”關(guān)鍵字可以用來忽略重復值。
注意: 如果Select list中多于一列,則distinct關(guān)鍵字對它們總體有效。如果一列有重復值,而其他列的值是唯一的,則有重復值的一列包含在結(jié)果中。
3. 在結(jié)果數(shù)據(jù)集合中對列重命名
結(jié)果中列的默認名字是源數(shù)據(jù)庫中的列名,用戶可以用自己指定的列名來代替默認的列名。
Select AuthorFirstName = au_fname from authors???
--將列名由“au_fname”改成“AuthorFirstName”
4. 選擇計算值
在Select list中可以包含計算值或常量。計算值是在算術(shù)表達式的基礎(chǔ)上計算而來的,它可包含在表中的一列或多列。
Select totalSale = price * ytd_sales from titles
條件選擇(Where子句)
使用一個比較或邏輯操作在Where子句中指定過濾條件,來生成表中想得到的行。
1.??比較操作
比較操作能比較數(shù)值、字符和日期數(shù)據(jù),返回TRUE或FALSE。
比較操作符
<(小于)
>(大于)
=(等于)
<>(不等于)
>=(大于等于)
<=(小于等于)
!=(不等于)
!<(不小于)
!>(不大于)
2.??邏輯操作
邏輯操作測試某些條件是否正確,并根據(jù)測試結(jié)果返回TRUE或FALSE。
· LIKE 如果操作和指定的字符串相同,則返回TRUE,指定的字符串也可包含通配符。
有通配符的like操作更有用。
????????· “%”規(guī)定所有字符串可代替字符“%”的位置。任何在“%”之前或之后的指定字符串視為常量。如:“New%”表示所有以“New”開頭的字符串,“%New”表示以“New”結(jié)尾的字符串。
????????· “_”規(guī)定任何單個字符可代入“_”的位置。這在只有一個字符不同的相近字符的情況下非常有用。
????????· “[]”規(guī)定使用方括號中定義的字符代替一個字符。方括號中可能是獨立的字符(如[ahg]),也可是字符范圍(如[c-i])。
· “[^]”規(guī)定方括號中“^”之后的字符為不能用來代入的字符,它可以是獨立字符(如[ahg]),也可是字符范圍(如[c-i])。
注意:可以在一個表達式中組合運用這些通配符。
· BETWEEN 如果操作數(shù)在提供的范圍之內(nèi),則返回TRUE。
BETWEEN可和NOT操作符一同使用,如果數(shù)據(jù)在指定范圍之外,則返回TRUE。
注意:BETTEN操作符是指定范圍。例如,BETWEEN A and B表示所有在A和B之間的值,包括A和B。
· IN 如果操作數(shù)和任意的指定值相匹配,則IN操作符返回TRUE。指定值可以是一個常量值列表,也可由另外的查詢(稱為子查詢)產(chǎn)生。
????IN操作符也可和NOT操作符聯(lián)合使用,如果數(shù)據(jù)不在指定值中,它返回TRUE。
· AND 它結(jié)合兩個表達式,如果兩個表達式都為TRUE,則它返回TRUE,否則返回FALSE。
· OR 它結(jié)合兩個表達式,如果兩個表達式中有一個為TRUE,則它返回TRUE,如果兩個都為FALSE,則返回FALSE。
· NOT 它對邏輯操作值求反,它可和大多數(shù)邏輯操作聯(lián)合使用,對操作返回的值求反。
· SOME|ANY 這兩個操作有相同的格式。它們把操作數(shù)和指定值的集合比較。如果操作數(shù)與任意指定值的比較返回TRUE,則它返回TRUE。比較操作可以是任意SQL Server定義的比較操作。指定值列表可以由另一個查詢產(chǎn)生。
· ALL ALL操作和SOME及ANY有相似的格式。不同的是,如果所有操作數(shù)和指定值的比較返回TRUE,它才返回TRUE。
數(shù)據(jù)排序
???????ORDER BY子句按指定的順序?qū)?shù)據(jù)排序(ordering data)。它要求一個列名字列表或非負整數(shù)列表來指定列的位置。分別用ASC代表升序,DESC代表降序,默認為ASC。
限制返回行的數(shù)目
???????不使用WHERE子句而限制結(jié)果中的行數(shù)是可能的。“TOP”子句能按指定數(shù)目或百分值來限制行數(shù)。
數(shù)據(jù)分組和計算聚合函數(shù)
???????聚合(aggregate)函數(shù)計算表中數(shù)據(jù)的總和。SQL Server提供以下的聚合函數(shù):
???????· AVG 這個函數(shù)計算平均值。語法如下:
???????AVG ([ALL | DISTINCT] expression)
???????關(guān)鍵字DISTINCT只用來計算不同值的平均值,如果有許多重復值,這些值只計算一次,默認為ALL。
???????Expression可以是涉及一列或多列的算術(shù)表達式。
???????· MIN 這個函數(shù)查找所提供表達式中的最小值。語法如下:
???????MIN (expression)
???????· MAX 此函數(shù)的功能是在提供的表達式中查找最大值。語法如下:
???????MAX (expression)
???????注意: 如果地字符串類型使用MIN和MAX,則輸出依賴于為SQL Server定義的順序。MIN和MAX不能在位上使用。
????· SUM SUM計算所有數(shù)據(jù)值的和。語法如下:
???????SUM ([ALL | DISTINCT] expression)
???????注意:SUM和AVG只能用于數(shù)值數(shù)據(jù)類型。
????· COUNT 計算表達式值的數(shù)目。語法如下:
???????COUNT ([ALL | DISTINCT] expression)
???????COUNT有另一種用法,它可以返回被選擇的行數(shù)。
???????如:SELECT NumRows = COUNT (*) FROM titles
???????聚合函數(shù)忽略所有空值,但COUNT(*)除外。盡管所有聚合函數(shù)的計算基于無空值的情況,然而COUNT(*)計算所有的行(包括有空值的行)。
1.??GROUP BY子句
GROUP BY子句在被定義的數(shù)據(jù)的基礎(chǔ)上建立比較小的組,并且對每一個組進行聚合函數(shù)計算。換句話說,它產(chǎn)生每一組的總體信息。GROUP BY可以把多于一列當成組合列(Grouping Columns)。它總結(jié)組合列中不重復值的信息。
使用了GROUP BY子句的選擇列表中只能包含以下項:
· 常量值。
· 組合列。
· 表達式。每個表達式為每組返回一個值(如聚合函數(shù))。如果一列除了在組合列中外,還在選擇列表中,則它有多個值給組合列的每一個不重復值,這種結(jié)構(gòu)類型是不允許的。
2.??GROUP BY和HAVING
HAVING子句用來向使用GROUP BY子句的查詢中增加數(shù)據(jù)過濾準則。HAVING的用法和SELECT中的WHERE子句一樣。在一個包含GROUP BY子句的查詢中使用WHERE子句是可以的。HAVING和WHERE有相同的語法。HAVING和WHERE的不同這處是:
· 在WHERE子句中,在分組進行以前,去除不滿足條件的行,在HAVING子句中,在分組之后條件被應用。
· HAVING可在條件中包含聚合函數(shù),但WHERE不能。
注意:GROUP BY和HAVING子句不能使用文本或圖像數(shù)據(jù)類型。
3.??COMPUTE BY子句
COMPUTE BY子句可以得到詳細或總的記錄。它把數(shù)據(jù)分成較小的組,然后為每組建立詳細記錄結(jié)果數(shù)據(jù)集(象SELECT),它也可為每組產(chǎn)生總的記錄(象GROUP BY)。
在COMPUT BY中,定義BY子句不是必要的。如果沒有定義BY子句,則認為整個表為一個組,并且只有兩個結(jié)果數(shù)據(jù)集產(chǎn)生,一個擁有所有詳細記錄,另一個只有一行,它擁有總記錄。
注意:當在COMPUTE中使用BY時,則要求在所有組合列中包含ORDER BY。
Cube和Rollup操作
????CUBE和ROLLUP操作可比簡單的GROUP BY產(chǎn)生更多的聚合值。在產(chǎn)生交叉標簽報告(cross tab reports)時,這些操作非常有用。如果查詢使用n個組合列,則有2n個計算聚合的組合。
從多個表中訪問數(shù)據(jù)
????我們已討論了如何訪問單個表中的數(shù)據(jù)。從多個表中訪問數(shù)據(jù)也是可能的。從多個表中訪問數(shù)據(jù)稱為連接表(joining a table)。
1、??CROSS JOIN(笛卡爾積)
CROSS JOIN是簡單地、不加任何約束條件地把表組合。CROSS JOIN后結(jié)果的行數(shù)是連接前兩個表行數(shù)的乘積。如果對兩個分別有好幾千行的表進行連接,則結(jié)果是不可想象的。
2、??INNER JOIN
INNER JOIN是組合兩個表最常用的方法。INNER JOIN是基于一個判別式進行的,這個判別式稱為連接條件。連接條件和WHERE子句一起定義。連接條件由來自兩個表中的列組成,并使用一個比較條件來對列的值進行比較。通過比較的值包含在結(jié)果數(shù)據(jù)集中,以下是Inner JOIN的語法:
語法1:(ANSI 92)
Select <select_list>
FROM <table1> INNER JOIN <table2>
ON <table1>.<column name> = <table2>.<column name>
語法2:
Select <select_list>
FROM <table1>,<table2> WHERE <table1>.<column name> = <table2>.<column name>
在FROM 子句中可為表定義別名,并在任何地方都可用別名代替真名。
注意:如果作為連接條件的列中有空值,則空值不能和任何值匹配,因此結(jié)果中不包含有空值的行。
3、??Left Outer JOIN
在Inner JOIN中,只有在兩個表中匹配的行才能在結(jié)果數(shù)據(jù)集中。但在Left Outer JOIN中,所有左邊表中的行都出現(xiàn)在結(jié)果數(shù)據(jù)集中,如果左邊表中的某一行在右邊表中沒有匹配的行,則以空值取代右邊表中的值和它連接。
語法如下:(ANSI 92)
Select <select_list>
FROM <table1> LEFT OUTER JOIN <table2>
ON <table1>.<column name> = <table2>.<column name>
4、??Right Outer JOIN
Right Out JOIN和Left Outer JOIN相似,不同的是把右邊的表作為外部表(所有右邊表中的行包含在結(jié)果數(shù)據(jù)集中)。
語法如下:
Select <select_list>
FROM <table1> RIGHT OUTER JOIN <table2>
ON <table1>.<column name> = <table2>.<column name>
5、??Full Outer JOIN
在Full Outer JOIN中,所有兩個表中的行都包含在結(jié)果數(shù)據(jù)集中。
語法如下:
Select <select_list>
FROM <table1> FULL OUTER JOIN <table2>
ON <table1>.<column name> = <table2>.<column name>
Case語句
????當對不同條件產(chǎn)生不同的結(jié)果值時,可使用Case語句。
????Case語句計算所有定義的條件,并按條件是否為真而返回結(jié)果。
語法如下:
CASE [<input_expression>]
WHEN <when_expression> THEN <result_expression>
[ELSE <else_expression>]
END
Input_expression是任何有效的SQL Server表達式或布爾表達式。
When_expression是任何有效的SQL Server表達式或布爾表達式。這個表達式和Input_expression比較,如果Input_expression沒有定義,則When_expression應該是一個布爾表達式。
Result_expression是任何有效的SQL Server表達式。如果When_expression和Input_expression的比較返回TRUE(如果定義了Input_expression)或When_expression的值為TRUE,則計算表達式,并返回其結(jié)果。否則計算Else_expression中的表達式,并返回其結(jié)果。
例如:
SELECT au_fname,au_lname,
State=CASE state
??????????????WHEN ‘CA’ THEN ‘California’
??????????????WHEN ‘KS’ THEN ‘Kansas’
?????????END
FROM authors
UNION
???????UNION語句把兩個或多個查詢的結(jié)果組合成一個結(jié)果集。
???????語法如下:
???????SELECT <select_list>
???????FROM <table_list>
???????WHERE <join_condition>
???????UNION [ALL]
???????SELECT <table_list>
???????FROM <table_list>
???????WHERE <join_condition>
???????ALL關(guān)鍵字指定重復的數(shù)據(jù)也將包含在最終結(jié)果數(shù)據(jù)集中。如果需要,一個查詢中可以有許多UNION語句。所有Select_list應該有相同數(shù)目的列,且是相同或兼容的數(shù)據(jù)類型。
Go命令???????Go命令用來標志一個查詢批處理(query batch)的結(jié)束。查詢批處理是TSQL語句的集合,這些語句集合在一起執(zhí)行。Go與Osql或SQL Server Query Analyzer一起使用。
管理文本和圖像數(shù)據(jù)
???????文本和圖像數(shù)據(jù)類型列可以象其它列一樣包含在SELECT語句的Select_list中。通過SELECT語句檢索的最大文本大小由TEXTSIZE設(shè)置來控制。默認的TEXTSIZE的值是4096字節(jié),使用SET TEXTSIZE語句可重新設(shè)置。當前的TEXTSIZE設(shè)置的值存放在全局變量@@TEXTSIZE中。
???????另一種檢索文本和圖像數(shù)據(jù)的方法是通過TEXTPTR和READTEXT函數(shù)。TEXTPTR函數(shù)把列名字作為輸入?yún)?shù)并以二進制格式返回文本指針。
???????這個指針和被稱為偏移量的讀開始指針以及要讀的字節(jié)數(shù)量一起傳給READTEXT函數(shù),以檢索文本和圖像數(shù)據(jù)。
修改數(shù)據(jù)
???????TSQL也提供從數(shù)據(jù)庫插入、修改、刪除的命令。
插入
???????INSERT命令用來在表中插入數(shù)據(jù),語法如下:
???????INSERT [INTO] <table_name> [(column_list)] VALUES (value_list)
???????Value_list是和在Column_list中列相應的值。這些值可以是常量、TSQL變量或SQL Server內(nèi)部函數(shù)。值的順序應和column_list中列的順序相對應。如果沒有定義column_list,則值的順序應和表中列的順序?qū)?br />???????INSERT的Values_list也可通過SELECT語句或一個存儲過程來提供。語法如下:
???????INSERT [INTO] <table_name> [(column_list)]
???????SELECT <select_list> FROM <table_name>
???????INSERT [INTO] <table_name> [(column_list)]
???????EXECUTE <procedure_name>
???????這里的SELECT語句可包含多種連接。如果使用存儲過程,則存儲過程應返回能作為column_list的結(jié)果。
???????時間戳(timestamp,又稱時標)值不應被提供。同時,如果列的IDENTITY屬性被定義,則這一列的值也不能提供。這些值都由系統(tǒng)產(chǎn)生。如果列有默認值,則它們的值不被提供,而使用默認值。
修改
???????UPDATE語句用來修改行,語法如下:
???????UPDATE <table_name> SET <column_name> = <value> [,<column_name> = <value>_n]
???????WHERE <search_condition>]
???????Serach_condition是要修改的行應滿足的條件。沒有WHERE子句的UPDATE語句將修改表中的所有行。在UPDATE語句中也可使用連接。
刪除
???????DELETE語句用來從表中刪除行。語法如下:
???????DELETE [FROM] <table_name>
???????[WHERE <search_condition>]???????Serach_condition是刪除行要滿足的條件。一個無條件DELETE語句將刪除表中的所有行。在DELETE語句中也可使用連接。
使用SQL Server開發(fā)應用程序
編寫存儲過程與觸發(fā)器
???????存儲過程和觸發(fā)器是由用戶創(chuàng)建的、駐留在服務(wù)器的一組Transact SQL查詢語句。觸發(fā)器是系統(tǒng)在特定條件下執(zhí)行的。存儲過程能夠改善應用程序的性能。當客戶程序需要訪問數(shù)據(jù)時,一般要經(jīng)過5個步驟才能訪問到數(shù)據(jù):
1)??查詢語句被發(fā)送到服務(wù)器。
2)??服務(wù)器編譯SQL代碼。
3)??優(yōu)化產(chǎn)生查詢的執(zhí)行計劃。
4)??數(shù)據(jù)引擎執(zhí)行查詢。
5)??結(jié)果發(fā)回客戶程序。
存儲過程是在創(chuàng)建時編譯的,當存儲過程第一次執(zhí)行時,SQL Server產(chǎn)生查詢執(zhí)行計劃并將其存儲進來,以利于將來使用。當通過存儲過程發(fā)出一個請求時,上述的第2和第3步就沒有了,這能大大改善系統(tǒng)的性能。即使在第1步上也能提高性能。因為此時發(fā)送到服務(wù)器的語句只是一條存儲過程的EXECUTE語句,而不是龐大的、復雜的查詢。這種特性能降低網(wǎng)絡(luò)的流量。
除了性能方面的改善外,存儲過程還提供了方便地集中維護應用程序的功能。如果將查詢嵌入到應用程序中。而又需要對查詢進行改變,則應用程序需要重新編譯,并重新發(fā)布到所有的客戶端。而在存儲過程中,修改對用戶而言是透明的,它只需要在服務(wù)器上重新編譯存儲過程。
存儲過程還能提供安全機制,盡管用戶可能無權(quán)執(zhí)行存儲過程中的命令,但它卻可能有權(quán)執(zhí)行存儲過程本身。有時候,系統(tǒng)管理員不會給用戶以數(shù)據(jù)修改(UPDATE、INSERT和DELETE)的權(quán)力。創(chuàng)建的存儲過程卻能進行這些操作。當然用戶需要擁有執(zhí)行該存儲過程的權(quán)力。
建立存儲過程
???????存儲過程可以達到以下目的:
???????· 帶參數(shù)。
???????· 返回狀態(tài)值。
???????· 調(diào)用其它存儲過程。
???????· 在遠程服務(wù)器上執(zhí)行。
???????存儲過程在“sysobjects”系統(tǒng)表中有一個表項,其類型為“P”。存儲過程的文本存儲在“syscomments”系統(tǒng)表中。創(chuàng)建存儲過程需要使用Transact SQL命令CREATE PROCEDURE。
???????例如:
???????USE pubs
???????GO
???????
???????CREATE PROCEDURE ap_GetAuthorsForPublisher
???????AS
???????SELECT a.au_lname,a.au_fname
???????FROM authors a, titleauthor ta, titles t, publishers p
???????WHERE a.au_id = ta.Au_id
???????AND ta.Title_id = t.title_id
???????AND t.pub_id = p.pub_id
???????AND p.pub_name = ’New Moon Books’
???????GO
???????CREATE PROCEDURE語句的語法如下:
???????CREATE PROC[DURE] procedure_name [;number]
??????????????[@parameter_name ][OUTPUT] [,_n] ]
??????????????[WITH {RECOMPILE | ENCRYPTION}]
??????????????[FOR REPLICATION]
???????AS
???????Number是用來對相同名字的過程進行分組的整數(shù)。分組是將所有的過程通過drop procedure語句組合到一個分組中。
???????@parameter_name指定參數(shù)的名稱。
???????RECOMPILE表示每次執(zhí)行過程時都要進行編譯。
???????ENCRYPTION表示過程的文本在“syscomments”表中要加密。
???????FOR REPLICATION表示過程不能在提交服務(wù)器上執(zhí)行。
將參數(shù)傳遞給存儲過程
???????存儲過程能夠接受參數(shù)。
???????注意:過程的參數(shù)也可以是用戶定義的數(shù)據(jù)類型。
給參數(shù)一個缺省值
???????用戶還可以為存儲過程中的參數(shù)定義缺省值。當在執(zhí)行時沒有提供所需的參數(shù)時,系統(tǒng)就使用缺省值作為參數(shù)。如果既沒有定義缺省值,又沒有在執(zhí)行時提供參數(shù),則SQL Server就會返回一個錯誤。在存儲過程中定義缺省值,并使用一些邏輯檢測是否指定了參數(shù)從而采取相應的行動,這是一種很好的習慣。
???????例如:
???????USE pubs
???????GO
???????
???????CREATE PROCEDURE ap_GetAuthorsForPublisher
???????@PublisherName varchar(40) = ‘New Moon Books’
???????AS
???????SELECT a.au_lname,a.au_fname
???????FROM authors a, titleauthor ta, titles t, publishers p
???????WHERE a.au_id = ta.Au_id
???????AND ta.Title_id = t.title_id
???????AND t.pub_id = p.pub_id
???????AND p.pub_name = @PublisherName
???????GO
建立存儲過程體
???????存儲過程邏輯駐留在存儲過程體中。一個存儲過程體中可以包含任意條Transact SQL語句。下面的Transact SQL語句不能在任何存儲過程體中出現(xiàn):
???????· CREATE DEFAULT
???????· CREATE TRIGGER
???????· CREATE PROCEDURE
???????· CREATE VIEW
???????· CREATE RULE
1、??局部變量
局部變量保持存儲過程中間值。當一個值在存儲過程中需要多次,或者某個查詢的結(jié)果需要在隨后的查詢中使用時,需要使用局部變量。在這些情形下,值被存儲在局部變量中,并可用于將來的使用。本地變量的名稱以“@”符號開頭。變量的名稱可以包含字符和數(shù)值。局部變量在使用前需要進行類型聲明。對局部變量進行賦值需要使用SELECT語句。SELECT可以從一個表中檢索出值并將其賦給某個變量,也可以給變量賦一個常量值。一個簡單的SELECT語句可以給多個局部變量賦值。
例如:
DECLARE @var1 integer, @var2 varchar(20)
SELECT @var1 = 32,
???????????@var2 = ‘MyAge’
如果從SELECT查詢中沒有返回任何數(shù)據(jù),而SELECT又要將數(shù)據(jù)的值賦予局部變量,則該局部變量的值將不會發(fā)生改變。
2、??條件詞句
存儲過程中提供的條件語句包括:
· IF……ELSE語句。
· WHILE語句。
1)??IF……ELSE語句。在該語句中包含三個部分:布爾運算表達式,IF語句塊和ELSE語句塊。語法如下:
IF (boolen_expr)
??{statements}
ELSE
??{statements}
在IF或ELSE語句塊中可以有多條語句,這種情形下,需要語句BEGIN和END來標志語句塊。
2)??WHILE語句。WHILE語句用于處理直到某個條件為TRUE前重復執(zhí)行的語句。語法如下:
WHILE (boolen_expr)
??BEGIN
??statement(s)
BREAK
Statement(s)
CONTINUE
??????????????END
????????????BEGIN和END語句標志循環(huán)體。BREAK語句結(jié)束循環(huán)的執(zhí)行(即走到END語句之后)。CONTINUE語句將控制處理過程回到循環(huán)的開始處(即BEGIN語句的右邊)。
????????????注意:如果有兩個或多個WHILE循環(huán)被嵌套,則內(nèi)部的BREAK退出的是次外層的循環(huán)。內(nèi)部循環(huán)結(jié)束之后的所有語句在內(nèi)部循環(huán)執(zhí)行之后才能繼續(xù)執(zhí)行。
3、??GOTO語句
在存儲過程的執(zhí)行中,語句是順序執(zhí)行的。GOTO語句則是用來打破這種語句執(zhí)行的順序,它立即跳到某條語句上執(zhí)行,而這條語句往往不緊跟在前一語句之后。GOTO語句與一個標志(Label)一起使用,該標志用來標識一條語句。
例如:
USE pubs
GO
DECLARE @num int
SELECT
IF @num = 0
???????GOTO Err
ELSE
???????BEGIN
???????PRINT ‘a(chǎn)uthors found’
???????SELECT * FROM authors
???????GOTO Last
???????END
Err: PRINT ‘no authors found’
Last: PRINT ‘Finish execution’
GO
4、??RETURN語句
RETURN語句用于無條件的退出存儲過程。RETURN之后的任何語句都不再執(zhí)行。RETURN語句可以給調(diào)用語句返回一個值,但不能返回NULL值。SQL Server經(jīng)常為存儲過程返回一個狀態(tài)值。如果成功地執(zhí)行,則返回一個0,如果出現(xiàn)了錯誤,則返回一個為負數(shù)的錯誤碼。
存儲過程返回的錯誤碼
值
說????????明
值
說????????明
0
過程執(zhí)行成功
-8
發(fā)生了非致命的內(nèi)部問題
-1
漏掉了對象
-9
達到了系統(tǒng)極限
-2
發(fā)生了數(shù)據(jù)類型錯誤
-10
發(fā)生了致命的內(nèi)部不一致錯誤
-3
該處理被選擇成了死鎖的犧牲者
-11
發(fā)生了致命的內(nèi)部不一致錯誤
-4
發(fā)生了權(quán)限錯誤
-12
表或索引被破壞
-5
發(fā)生了語法錯誤
-13
數(shù)據(jù)庫被破壞
-6
發(fā)生了混雜的用戶錯誤
-14
發(fā)生了硬件錯誤
-7
資源錯誤,如空間不夠等
5、??使用游標(CURSOR)在需要一行一行處理時,游標十分有用。游標可以打開一個結(jié)果集合(按照指定的標準選擇的行),并提供在結(jié)果集中一行一行處理的功能。基于游標的類型,可以對其進行回滾或者前進。在使用游標時需要5個步驟:
i.??????????????聲明游標
在這一步中,需要指定游標的屬性和根據(jù)要求產(chǎn)生的結(jié)果集。有兩種方法可以指定一個游標。
形式1??(ANSI 92)
DECLARE cursor_name [INSENSITIVE] [SCROLL] CURSOR
FOR select_statement
[FOR {READ ONLY | UPDATE ][OF column_list]}]
形式2
DECLARE cursor_name CURSOR
[LOCAL | GLOBAL]
[FORWARD_ONLY | SCROLL]
[STATIC | KEYSET | DYNAMIC]
[READ_ONLY | SCROLL_LOCKS | OPTIMISTIC]
FOR select_statement
[FOR {READ ONLY | UPDATE ][OF column_list]}]
INSENSITIVE關(guān)鍵字指明要為檢索到的結(jié)果集建立一個臨時拷貝,以后的數(shù)據(jù)從這個臨時拷貝中獲取。如果在后來游標處理的過程中,原有基表中數(shù)據(jù)發(fā)生了改變,那么它們對于該游標而言是不可見的。這種不敏感的游標不允許數(shù)據(jù)更改。
SCROLL關(guān)鍵字指明游標可以在任意方向上滾動。所有的fetch選項(first、last、next、relative、absolute)都可以在游標中使用。如果忽略該選項,則游標只能向前滾動(next)。
Select_statement指明SQL語句建立的結(jié)果集。Transact SQL語句COMPUTE、COMPUTE BY、FOR BROWSE和INTO在游標聲明的選擇語句中不允許使用。
READ ONLY指明在游標結(jié)果集中不允許進行數(shù)據(jù)修改。
UPDATE關(guān)鍵字指明游標的結(jié)果集可以修改。
OF column_list指明結(jié)果集中可以進行修改的列。缺省情況下(使用UPDATE關(guān)鍵字),所有的列都可進行修改。
LOCAL關(guān)鍵字指明游標是局部的,它只能在它所聲明的過程中使用。
GLOBAL關(guān)鍵字使得游標對于整個連接全局可見。全局的游標在連接激活的任何時候都是可用的。只有當連接結(jié)束時,游標才不再可用。
FORWARD_ONLY指明游標只能向前滾動。
STATIC的游標與INSENSITIVE的游標是相同的。
KEYSET指明選取的行的順序。SQL Server將從結(jié)果集中創(chuàng)建一個臨時關(guān)鍵字集。如果對數(shù)據(jù)庫的非關(guān)鍵字列進行了修改,則它們對游標是可見的。因為是固定的關(guān)鍵字集合,所以對關(guān)鍵字列進行修改或新插入列是不可見的。
DYNAMIC指明游標將反映所有對結(jié)果集的修改。
SCROLL_LOCK是為了保證游標操作的成功,而對修改或刪除加鎖。
OPTIMISTIC指明哪些通過游標進行的修改或者刪除將不會成功。
注意:
· 如果在SELECT語句中使用了DISTINCT、UNION、GROUP BY語句,且在選擇中包含了聚合表達式,則游標自動為INSENSITIVE的游標。
· 如果基表沒有唯一的索引,則游標創(chuàng)建成INSENSITIVE的游標。
· 如果SELECT語句包含了ORDER BY,而被ORDER BY的列并非唯一的行標識,則DYNAMIC游標將轉(zhuǎn)換成KEYSET游標。如果KEYSET游標不能打開,則將轉(zhuǎn)換成INSENSITIVE游標。使用SQL ANSI-92語法定義的游標同樣如此,只是沒有INSENSITIVE關(guān)鍵字而已。
???????????????????????ii.??????????????打開游標
打開游標就是創(chuàng)建結(jié)果集。游標通過DECLARE語句定義,但其實際的執(zhí)行是通過OPEN語句。語法如下:
OPEN { { [GLOBAL] cursor_name } | cursor_variable_name}
GLOBAL指明一個全局游標。
Cursor_name是被打開的游標的名稱。
Cursor_variable_name是所引用游標的變量名。該變量應該為游標類型。
在游標被打開之后,系統(tǒng)變量@@cursor_rows可以用來檢測結(jié)果集的行數(shù)。@@cursor_rows為負數(shù)時,表示游標正在被異步遷移,其絕對值(如果@@cursor_rows為-5,則絕對值為5)為當前結(jié)果集的行數(shù)。異步游標使用戶在游標被完全遷移時仍然能夠訪問游標的結(jié)果。
??????????????????????iii.??????????????從游標中取值
在從游標中取值的過程中,可以在結(jié)果集中的每一行上來回移動和處理。如果游標定義成了可滾動的(在聲明時使用SCROLL關(guān)鍵字),則任何時候都可取出結(jié)果集中的任意行。對于非滾動的游標,只能對當前行的下一行實施取操作。結(jié)果集可以取到局部變量中。Fetch命令的語法如下:
FETCH [NEXT | PRIOR| FIRST | LAST | ABSOLUTE {n | @nvar} | RELATIVE {n | @nvar}]
FROM [GLOBAL] cursor_name} | cursor_variable_name}
[INTO @variable_name ][,……n]]
NEXT指明從當前行的下一行取值。
PRIOR指明從當前行的前一行取值。
FIRST是結(jié)果集的第一行。
LAST是結(jié)果集的最后一行。
ABSOLUTE n表示結(jié)果集中的第n行,該行數(shù)同樣可以通過一個局部變量傳播。行號從0開始,所以n為0時不能得到任何行。
RELATIVE n表示要取出的行在當前行的前n行或后n行的位置上。如果該值為正數(shù),則要取出的行在當前行前n行的位置上,如果該值為負數(shù),則返回當前行的后n行。
INTO @cursor_variable_name表示游標列值存儲的地方的變量列表。該列表中的變量數(shù)應該與DECLARE語句中選擇語句所使用的變量數(shù)相同。變量的數(shù)據(jù)類型也應該與被選擇列的數(shù)據(jù)類型相同。直到下一次使用FETCH語句之前,變量中的值都會一直保持。
每一次FETCH的執(zhí)行都存儲在系統(tǒng)變量@@fetch_status中。如果FETCH成功,則@@fetch_status被設(shè)置成0。@@fetch_status為-1表示已經(jīng)到達了結(jié)果集的一部分(例如,在游標被打開之后,基表中的行被刪除)。@@fetch_status可以用來構(gòu)造游標處理的循環(huán)。
例如:
DECLARE @iname char(20), @fname char(20)
OPEN author_cur
FETCH FIRST FROM author_cur INTO @iname, @fname
WHILE @@fetch_status = 0
BEGIN
IF @fname = ‘Albert’
PRINT “Found Albert Ringer”
ELSE
Print “Other Ringer”
FETCH NEXT FROM author_cur INTO @iname, @fname
END
?????????????????????iv.??????????????關(guān)閉游標
CLOSE語句用來關(guān)閉游標并釋放結(jié)果集。游標關(guān)閉之后,不能再執(zhí)行FETCH操作。如果還需要使用FETCH語句,則要重新打開游標。語法如下:
CLOSE [GLOBAL] cursor_name | cursor_variable_name
???????????????????????v.??????????????釋放游標
游標使用不再需要之后,要釋放游標。DEALLOCATE語句釋放數(shù)據(jù)結(jié)構(gòu)和游標所加的鎖。語法如下:
DEALLOCATE [GLOBAL] cursor_name | cursor_variable_name
???????下面給出游標的一個完整的例子:
???????USE master
???????GO
???????CREATE PROCEDURE sp_BuildIndexes
???????AS
???????DECLARE @TableName sysname, @msg varchar(100), @cmd varchar(100)
???????DECLARE table_cur CURSOR FOR
???????SELECT name FROM sysobjects WHERE type=’u’
???????OPEN table_cur
???????FETCH NEXT FROM table_cur INTO @TableName
???????
???????WHILE @@fetch_status = 0
???????BEGIN
??????????????IF @@fetch_status = -2
?????????????????????CONTINUE
??????????????SELECT @msg = “Building indexes for table”+@TableName+”…”
??????????????PRINT @msg
??????????????SELECT @cmd = “DBCC DBREINDEX (‘”+@TableName+”')”
??????????????EXEC (@cmd)
??????????????PRINT “????“
??????????????FETCH NEXT FROM table_cur INTO @TableName
???????END
???????DEALLOCATE table_cur
???????GO
???????下面的腳本將為PUBS數(shù)據(jù)庫執(zhí)行sp_BuildIndexes
???????USE pubs
???????GO
???????EXEC ap_BuildIndexes
???????注意:上面也是創(chuàng)建用戶定義的系統(tǒng)存儲過程的示例。
使用臨時表
???????臨時表是在TempDB中創(chuàng)建的表。臨時表的名稱都以“#”開頭。臨時表的范圍為創(chuàng)建臨時表的連接。因為,臨時表不能在兩個連接之間共享,一旦連接關(guān)閉,臨時表就會被丟棄。如果臨時表被創(chuàng)建于存儲過程之中,則臨時表的范圍在存儲過程之中,或者被該存儲過程調(diào)用的任何存儲過程之中。如果需要在連接之間共享臨時表,則需要使用全局的臨時表。全局的臨時表以“##”符號開頭,它將一直存在于數(shù)據(jù)庫中,直到SQL Server重新啟動。一旦這類臨時表創(chuàng)建之后,所有的用戶都可以訪問到。在臨時表上不能明確地指明權(quán)限。???????臨時表提供了存儲中間結(jié)果的能力。有時候,臨時表還能通過將一個復雜的查詢分解成兩個查詢而獲得性能的改善。這可以通過首先將第一個查詢的結(jié)果存在臨時表中,然后在第二個查詢中使用臨時表來實現(xiàn)。當一個大表中的某個子集在一個在座過程中使用多次時,建議使用臨時表。在這種情況下,在臨時表中保持數(shù)據(jù)的子集,以在隨后的連接中使用,這樣能大大改善性能。還可以在臨時表中創(chuàng)建索引。
存儲過程中返回結(jié)果
???????從存儲過程中返回結(jié)果有三種方式:
1、??返回結(jié)果集
這是客戶端應用程序返回結(jié)果的最通用的方法。結(jié)果集是通過使用SELECT語句選擇數(shù)據(jù)產(chǎn)生的。結(jié)果集可以從永久表、臨時表或局部變量中產(chǎn)生。將結(jié)果返回到另一個存儲過程不是一種有效的方法。存儲過程不能訪問另一個存儲過程建立的結(jié)果集。
例如從永久表中返回結(jié)果集:
USE pubs
GO
CREATE PROCEDURE ap_CreateResultFromPermtable
AS
SELECT au_iname FROM authors
GO
例如從局部變量中創(chuàng)建結(jié)果集:
USE pubs
GO
CREATE PROCEDURE ap_CreateResultFromVariable
AS
DECLARE @au_iname char(20)
SELECT @au_iname = au_iname FROM authors
WHERE au_id = ‘172-32-1176’
SELECT @au_id
GO
2、??設(shè)置OUTPUT參數(shù)的值
輸出參數(shù)經(jīng)常用來從存儲過程中檢索出結(jié)果。如果某個參數(shù)在傳輸?shù)酱鎯^程中時被定義成OUTPUT,則對該參數(shù)的任何修改在退出存儲之后仍然有效。
例如:
USE pubs
GO
CREATE PROCEDURE ap_SetOutputVar @count integer OUTPUT
AS
SELECT @count = count(*) FROM authors
GO
從輸出參數(shù)中檢索出值:
USE pubs
GO
CREATE PROCEDURE ap_GetOutputVar
AS
DECLARE @num integer
EXECUTE ap_SetOutputVar @num OUTPUT
PRINT “the count is”+convert(char,@num)
GO
· 將游標使用成OUTPUT參數(shù)。游標可以使用OUTPUT(輸出)參數(shù),但不能使用成輸入?yún)?shù)。也就是說,游標可以作為結(jié)果返回,但卻不能傳輸?shù)竭^程中去。當游標被用作參數(shù)時,需要限定其為OUTPUT和VARYING。VARYING關(guān)鍵字指出該結(jié)果集要用來支持輸出參數(shù)。這樣就提供了將結(jié)果集返回到調(diào)用過程的能力。
例如:
USE pubs
GO
CREATE PROCEDURE GetTitleCount @count_cursor CURSOR VARYING OUTPUT
AS
SET @count_cursor = CURSOR
FOR
SELECT au_id,count(*)
FROM titleauthors
GROUP BY au_id
OPEN @count_cursor
GO
3、??通過RETURN參數(shù)返回狀態(tài)
這是一種從存儲過程返回錯誤碼的方法。存儲過程總是返回一個狀態(tài)值,用戶也可以使用RETURN語句返回自己的狀態(tài)。
例如:
USE pubs
GO
CREATE PROCEDURE ap_SetReturnStatus
AS
DECLARE @count integer
SELECT @count = count(*) FROM authors
IF @count = 0
RETURN(1)
ELSE
RETURN (0)
GO
例如檢索出返回的狀態(tài):
USE pubs
GO
CREATE PROCEDURE ap_GetReturnStatus
AS
DECLARE @status integer
EXECUTE @status = ap_SetReturnStatus
IF @status = 1
PRINT “No rows found”
ELSE
PRINT “successful”
GO
在存儲過程中進行錯誤處理
???????如同其它程序一樣,在存儲過程中進行錯誤處理是非常重要的。系統(tǒng)變更@@error在執(zhí)行每一個Transact SQL語句之后都會得到一個值。對于成功的執(zhí)行,@@error的值為0,如果出現(xiàn)錯誤,則@@error中將包含錯誤信息。@@error系統(tǒng)變量對存儲過程的錯誤處理是非常重要的。
???????注意:為了防止錯誤,@@error所能設(shè)置的值在sysmessages表的“error”中反映了出來。
在存儲過程中的錯誤有兩種類型:
1、????數(shù)據(jù)庫相關(guān)的錯誤
這些錯誤是由數(shù)據(jù)庫的不一致性引起的,系統(tǒng)使用非0的@@error值表示特定的數(shù)據(jù)庫問題。在Transact SQL執(zhí)行之后,可以通過@@error獲得所出現(xiàn)的錯誤。如果發(fā)現(xiàn)@@error不為0,則必須采取必要的行動,大多數(shù)情況下,存儲將不再繼續(xù)進行處理而返回。下面的示例展示了典型的獲取數(shù)據(jù)庫錯誤的方法。該過程將錯誤代碼放置到輸出變量中,這樣,調(diào)用程序就能夠訪問到。
USE pubs
GO
CREATE PROCEDURE ap_TrapDatabaseError @return_code integer OUTPUT
AS
UPDATE authors SET au_iname = “Jackson”
WHERE au_iname = “Smith”
IF @@error <> 0
BEGIN
???????SELECT @return_code = @@error
???????RETURN
END
ELSE
???????@return_code = 0
GO
2、????業(yè)務(wù)邏輯錯誤
這些錯誤是由于違反了業(yè)務(wù)規(guī)則而引起的。要獲取這些錯誤,首先需要定義業(yè)務(wù)規(guī)則,基于這些規(guī)則,需要在存儲過程中增加必要的錯誤檢測代碼。人們經(jīng)常使用RAISERROR語句通報這些錯誤。RAISERROR提供了返回用戶定義錯誤及將@@error變量設(shè)置成用戶定義錯誤號的能力。錯誤消息可以被動態(tài)地建立,或者基于錯誤號從“sysmessages”表中檢索到。一旦出現(xiàn)了錯誤,錯誤就會以一種服務(wù)器錯誤消息的方式返回到客戶機。下面是RAISERROR命令的語法:
RAISERROR (msg_id | msg_str, severity, state
[, argument ][,…n]])
[WITH options]
Msg_id指明用戶定義消息的id,該消息存儲在“sysmessages”系統(tǒng)表中。
Msg_str用于動態(tài)創(chuàng)建消息的消息字符串。這與C語言中的“printf”非常相似。
Severity定義用戶賦值的錯誤消息嚴重程度。
State是從1到127的任意整數(shù)值,它表示錯誤的調(diào)用狀態(tài)信息。負數(shù)的state值將缺省為1。
OPTIONS指明錯誤的定制選項。OPTIONS的有效值如下:
1)??LOG。
將錯誤記錄到服務(wù)器錯誤日志和NT事件日志中。該選項需要消息帶有從19到25的嚴重程度。而只有系統(tǒng)管理員才能發(fā)出這種消息。
2)??NOWAIT。
將消息立即發(fā)送到客戶端服務(wù)器。
3)??SETERROR。
不管其嚴重級別如何,將@@error的值設(shè)置為msg_id或5000。
遠程過程調(diào)用
???????SQL Server提供了調(diào)用駐留在不同服務(wù)器上的存儲過程的能力。調(diào)用這樣的存儲過程稱謂遠程存儲過程調(diào)用。為了使得調(diào)用能從一個SQL Server轉(zhuǎn)移到另一個服務(wù)器,兩個服務(wù)器應該相互定義成對方的有效遠程服務(wù)器。
???????設(shè)置遠程服務(wù)器的配置:
???????· 擴展某個服務(wù)器的組。
???????· 右擊該服務(wù)器并點擊“Properties”。
???????· 設(shè)置選項“Allow other SQL Servers to connect remotely to this SQL server via RPC”。
???????· 設(shè)置“Query time out”選項的值,該值指定從一個查詢處理返回所能等待的秒數(shù)。缺省值為0,表示允許無限的等待時間。
???????· 設(shè)置完成配置選項之后,點擊“OK”。
???????· 重新啟動服務(wù)器之后,修改將會生效。
???????· 在另一臺遠程服務(wù)器上重復相同的步驟。
???????調(diào)用遠程存儲過程需要指明服務(wù)器的名稱,后帶數(shù)據(jù)庫的名稱和擁有者的名稱。下面是在不同的服務(wù)器(Server2)上調(diào)用一個存儲過程的示例。
Exec server2.pubs.dbo.myproc
豆豆的后話:
???????這里只是粗淺的介紹了SQL Server常用的知識,對象也是基于SQL Server數(shù)據(jù)庫編寫應用程序的編程人員,而非數(shù)據(jù)庫管理者。但對于應用程序編程者,了解數(shù)據(jù)庫的管理也是非常有用的。建議在以后的時間自行去了解數(shù)據(jù)庫的管理,這對于優(yōu)化程序也是相當有用的。
————————全文完—————————
它是SQL Server的查詢語言。提供以下命令:
· 創(chuàng)建和數(shù)據(jù)庫對象。
· 訪問和修改數(shù)據(jù)。
· 數(shù)據(jù)聚合(aggregation,又稱聚集)。
· 實施安全措施。
數(shù)據(jù)庫對象
???????數(shù)據(jù)庫對象是數(shù)據(jù)庫中的物理對象。這些對象擁有唯一的名字,并保存數(shù)據(jù)和數(shù)據(jù)關(guān)系信息。SQL Server定義了如下幾種對象:
1、 表(table)
表是用來存儲數(shù)據(jù)的兩維數(shù)組,它有行和列。列也稱為表屬性或字段,表中的每一列擁有唯一的名字,每一列包含具體的數(shù)據(jù)類型,這個數(shù)據(jù)類型由列中的數(shù)據(jù)類型定義。
2、 視圖(view)
視圖是虛擬的表,它只包含表的一部分。與表不同的是,保存在視圖中的數(shù)據(jù)并不是物理存儲的數(shù)據(jù),它是由表派生的,派生表被稱為視圖的基本表。視圖的定義存儲在數(shù)據(jù)庫中。
3、 約束條件(constraint)
約束條件定義數(shù)據(jù)的完整性和有效性。約束條件為列中的值建立規(guī)則。換而言之,如果在某一列上定義了結(jié)束條件,則插入這一列的每一個值需要通過約束條件檢查。約束條件是在觸發(fā)器和規(guī)則上保證數(shù)據(jù)完整性和有效性的較佳選擇。SQL Server Query Optimizer利用約束條件產(chǎn)生出低成本的查詢計劃。約束條件有如下類型:
· NOT NULL 這個約束條件要求列中不能有NULL值。
· CHECK 為列指定能擁有的值的集合后,檢查約束條件。列中任何在定義之外的數(shù)據(jù)都為無效數(shù)據(jù)。有效值集合稱為列的域。
· PRIMARY KEY 主關(guān)鍵字是列或列組合,它用來唯一標識一行。
· FOREIGN KEY 用來定義兩個表之間的父子關(guān)系。如果一個關(guān)鍵字既是一個表的主關(guān)鍵字的一部分,同時又是另一個表的主關(guān)鍵字,則稱它為外來關(guān)鍵字。外來關(guān)鍵字用來定義數(shù)據(jù)的引用完整性。
· UNIQUE 唯一約束條件是指無任何兩行在列中有相同的NON-NULL值。唯一性由主關(guān)鍵字保證,但他們不允許NULL值,并且每一個表只能有一個關(guān)鍵字。
4、 默認值(default)
默認值是為列定義的值,如果在插入一行時沒有提供某一列的值,則此列使用默認值,默認值可以是以下的一種:
· 常量
· 數(shù)學表達式
· 內(nèi)部函數(shù)(Built-in function)
5、 規(guī)則(rule)
規(guī)則執(zhí)行和CHECK約束條件同樣的功能。但規(guī)則和約束條件不同的是:規(guī)則作為獨立的對象存在,它可以用于多個表,而約束條件作為表的一部分存儲。然而,規(guī)則是作為向后兼容特點而提供的,建議用戶使用約束條件。
6、 觸發(fā)器和存儲過程
觸發(fā)器和存儲過程是一個TSQL命令集,它們作為一個對象存儲在數(shù)據(jù)庫中。
對象命名約定
SQL Server用三段式(three-part)名字標識對象:
<數(shù)據(jù)庫名>.<所有者名>.<對象名>
前兩部分可以省略,系統(tǒng)有一個默認值。數(shù)據(jù)庫名的默認值是當前數(shù)據(jù)庫,所有者名的默認值是數(shù)據(jù)庫所有者(dbo)。
數(shù)據(jù)類型
???????任何包含數(shù)據(jù)的對象都有一個數(shù)據(jù)類型和它關(guān)聯(lián)。數(shù)據(jù)類型是指定對象能包含何種數(shù)據(jù)的屬性。
???????SQL Server數(shù)據(jù)類型
數(shù)據(jù)類型
說??明
同??義
Bit
1位,值為0或1
Int
Integer
4字節(jié),值為-2^31~2^31-1
Smallint
2字節(jié),值為-2^15~2^15-1
Tinyint
1字節(jié),值為0~255
Decimal (p,s)
數(shù)字數(shù)據(jù),固定精度為P,寬度為S
Numeric
Money
8字節(jié),存放貨幣類型,值為-2^63~2^63-1
Small money
4字節(jié),存放貨幣類型,值為-214748.3648~+214748.3647近似數(shù)值數(shù)據(jù)類型
Float (n)
N在1~24之間,4字節(jié),7位精度
N=1~7為real
N在25~53之間,8字節(jié),15位精度
=8~15為float
Datetime
8字節(jié),描述某天的日期和時刻,值的精確度為1/300秒
Smalldatetime
4字節(jié),描述某天的日期和時刻,精度為分鐘
Cursor
對游標的引用
Timestamp
8字節(jié),存放在數(shù)據(jù)庫內(nèi)唯一的數(shù)據(jù)
Uniqueidentifier
16字節(jié),存放全局唯一標識(GUID)
Char (n)
非unicode字符串的固定長度,n=1~8000
Character (n)
Varchar (n)
可變長度,非unicode字符串n=1~8000
Char varying(n)
Text
服務(wù)器代碼頁中可變長度非unicode數(shù)據(jù)。最大長度為231-1個字符
Nchar
固定長度unicode字符串n=1~4000
National character (n),
National char(n)
Nvarchar
固定長度unicode字符串n=1~4000
National character varying(n)
Ntext
可變長度unicode數(shù)據(jù),最大長度為230-1個字符
National text
Binary (n)
固定長度二進制數(shù)據(jù),n在1~8000之間,存儲空間為n+4字節(jié)
Varbinary (n)
可變長度二進制數(shù)據(jù),n=1~8000
Binary varying (n)
Tmage
可變長度二進制數(shù)據(jù),大小為0~231-1
注意:
1)????對于數(shù)值型數(shù)據(jù)類型,寬度(scale)是指存儲在小數(shù)點后的數(shù)字位數(shù),而精度(precision)是指能存儲的包含小數(shù)點在內(nèi)的所有數(shù)字位數(shù)。
2)????money和small money的存儲寬度為4。
3)????時間戳列值在每一行更新時系統(tǒng)自動更新,時間戳列不能是關(guān)鍵字或關(guān)鍵字的一部分。
4)????唯一標識數(shù)據(jù)類型不能使用算術(shù)操作符(如+、-等),這種數(shù)據(jù)類型只能使用相等比較操作。Unicode是所有字符集的一致存儲數(shù)據(jù)的標準。它要使用兩倍于非Unicode數(shù)據(jù)存儲的存儲空間。
存取數(shù)據(jù)
select語句
1. 選擇表中的所有列
“*”對Select語句有特殊意義。它指定表中的所有列,而不用列出列的名字。列的順序和表中的順序相同。
2. 選擇不同的值
如果被選擇列表中的列有重復值,這時“distinct”關(guān)鍵字可以用來忽略重復值。
注意: 如果Select list中多于一列,則distinct關(guān)鍵字對它們總體有效。如果一列有重復值,而其他列的值是唯一的,則有重復值的一列包含在結(jié)果中。
3. 在結(jié)果數(shù)據(jù)集合中對列重命名
結(jié)果中列的默認名字是源數(shù)據(jù)庫中的列名,用戶可以用自己指定的列名來代替默認的列名。
Select AuthorFirstName = au_fname from authors???
--將列名由“au_fname”改成“AuthorFirstName”
4. 選擇計算值
在Select list中可以包含計算值或常量。計算值是在算術(shù)表達式的基礎(chǔ)上計算而來的,它可包含在表中的一列或多列。
Select totalSale = price * ytd_sales from titles
條件選擇(Where子句)
使用一個比較或邏輯操作在Where子句中指定過濾條件,來生成表中想得到的行。
1.??比較操作
比較操作能比較數(shù)值、字符和日期數(shù)據(jù),返回TRUE或FALSE。
比較操作符
<(小于)
>(大于)
=(等于)
<>(不等于)
>=(大于等于)
<=(小于等于)
!=(不等于)
!<(不小于)
!>(不大于)
2.??邏輯操作
邏輯操作測試某些條件是否正確,并根據(jù)測試結(jié)果返回TRUE或FALSE。
· LIKE 如果操作和指定的字符串相同,則返回TRUE,指定的字符串也可包含通配符。
有通配符的like操作更有用。
????????· “%”規(guī)定所有字符串可代替字符“%”的位置。任何在“%”之前或之后的指定字符串視為常量。如:“New%”表示所有以“New”開頭的字符串,“%New”表示以“New”結(jié)尾的字符串。
????????· “_”規(guī)定任何單個字符可代入“_”的位置。這在只有一個字符不同的相近字符的情況下非常有用。
????????· “[]”規(guī)定使用方括號中定義的字符代替一個字符。方括號中可能是獨立的字符(如[ahg]),也可是字符范圍(如[c-i])。
· “[^]”規(guī)定方括號中“^”之后的字符為不能用來代入的字符,它可以是獨立字符(如[ahg]),也可是字符范圍(如[c-i])。
注意:可以在一個表達式中組合運用這些通配符。
· BETWEEN 如果操作數(shù)在提供的范圍之內(nèi),則返回TRUE。
BETWEEN可和NOT操作符一同使用,如果數(shù)據(jù)在指定范圍之外,則返回TRUE。
注意:BETTEN操作符是指定范圍。例如,BETWEEN A and B表示所有在A和B之間的值,包括A和B。
· IN 如果操作數(shù)和任意的指定值相匹配,則IN操作符返回TRUE。指定值可以是一個常量值列表,也可由另外的查詢(稱為子查詢)產(chǎn)生。
????IN操作符也可和NOT操作符聯(lián)合使用,如果數(shù)據(jù)不在指定值中,它返回TRUE。
· AND 它結(jié)合兩個表達式,如果兩個表達式都為TRUE,則它返回TRUE,否則返回FALSE。
· OR 它結(jié)合兩個表達式,如果兩個表達式中有一個為TRUE,則它返回TRUE,如果兩個都為FALSE,則返回FALSE。
· NOT 它對邏輯操作值求反,它可和大多數(shù)邏輯操作聯(lián)合使用,對操作返回的值求反。
· SOME|ANY 這兩個操作有相同的格式。它們把操作數(shù)和指定值的集合比較。如果操作數(shù)與任意指定值的比較返回TRUE,則它返回TRUE。比較操作可以是任意SQL Server定義的比較操作。指定值列表可以由另一個查詢產(chǎn)生。
· ALL ALL操作和SOME及ANY有相似的格式。不同的是,如果所有操作數(shù)和指定值的比較返回TRUE,它才返回TRUE。
數(shù)據(jù)排序
???????ORDER BY子句按指定的順序?qū)?shù)據(jù)排序(ordering data)。它要求一個列名字列表或非負整數(shù)列表來指定列的位置。分別用ASC代表升序,DESC代表降序,默認為ASC。
限制返回行的數(shù)目
???????不使用WHERE子句而限制結(jié)果中的行數(shù)是可能的。“TOP”子句能按指定數(shù)目或百分值來限制行數(shù)。
數(shù)據(jù)分組和計算聚合函數(shù)
???????聚合(aggregate)函數(shù)計算表中數(shù)據(jù)的總和。SQL Server提供以下的聚合函數(shù):
???????· AVG 這個函數(shù)計算平均值。語法如下:
???????AVG ([ALL | DISTINCT] expression)
???????關(guān)鍵字DISTINCT只用來計算不同值的平均值,如果有許多重復值,這些值只計算一次,默認為ALL。
???????Expression可以是涉及一列或多列的算術(shù)表達式。
???????· MIN 這個函數(shù)查找所提供表達式中的最小值。語法如下:
???????MIN (expression)
???????· MAX 此函數(shù)的功能是在提供的表達式中查找最大值。語法如下:
???????MAX (expression)
???????注意: 如果地字符串類型使用MIN和MAX,則輸出依賴于為SQL Server定義的順序。MIN和MAX不能在位上使用。
????· SUM SUM計算所有數(shù)據(jù)值的和。語法如下:
???????SUM ([ALL | DISTINCT] expression)
???????注意:SUM和AVG只能用于數(shù)值數(shù)據(jù)類型。
????· COUNT 計算表達式值的數(shù)目。語法如下:
???????COUNT ([ALL | DISTINCT] expression)
???????COUNT有另一種用法,它可以返回被選擇的行數(shù)。
???????如:SELECT NumRows = COUNT (*) FROM titles
???????聚合函數(shù)忽略所有空值,但COUNT(*)除外。盡管所有聚合函數(shù)的計算基于無空值的情況,然而COUNT(*)計算所有的行(包括有空值的行)。
1.??GROUP BY子句
GROUP BY子句在被定義的數(shù)據(jù)的基礎(chǔ)上建立比較小的組,并且對每一個組進行聚合函數(shù)計算。換句話說,它產(chǎn)生每一組的總體信息。GROUP BY可以把多于一列當成組合列(Grouping Columns)。它總結(jié)組合列中不重復值的信息。
使用了GROUP BY子句的選擇列表中只能包含以下項:
· 常量值。
· 組合列。
· 表達式。每個表達式為每組返回一個值(如聚合函數(shù))。如果一列除了在組合列中外,還在選擇列表中,則它有多個值給組合列的每一個不重復值,這種結(jié)構(gòu)類型是不允許的。
2.??GROUP BY和HAVING
HAVING子句用來向使用GROUP BY子句的查詢中增加數(shù)據(jù)過濾準則。HAVING的用法和SELECT中的WHERE子句一樣。在一個包含GROUP BY子句的查詢中使用WHERE子句是可以的。HAVING和WHERE有相同的語法。HAVING和WHERE的不同這處是:
· 在WHERE子句中,在分組進行以前,去除不滿足條件的行,在HAVING子句中,在分組之后條件被應用。
· HAVING可在條件中包含聚合函數(shù),但WHERE不能。
注意:GROUP BY和HAVING子句不能使用文本或圖像數(shù)據(jù)類型。
3.??COMPUTE BY子句
COMPUTE BY子句可以得到詳細或總的記錄。它把數(shù)據(jù)分成較小的組,然后為每組建立詳細記錄結(jié)果數(shù)據(jù)集(象SELECT),它也可為每組產(chǎn)生總的記錄(象GROUP BY)。
在COMPUT BY中,定義BY子句不是必要的。如果沒有定義BY子句,則認為整個表為一個組,并且只有兩個結(jié)果數(shù)據(jù)集產(chǎn)生,一個擁有所有詳細記錄,另一個只有一行,它擁有總記錄。
注意:當在COMPUTE中使用BY時,則要求在所有組合列中包含ORDER BY。
Cube和Rollup操作
????CUBE和ROLLUP操作可比簡單的GROUP BY產(chǎn)生更多的聚合值。在產(chǎn)生交叉標簽報告(cross tab reports)時,這些操作非常有用。如果查詢使用n個組合列,則有2n個計算聚合的組合。
從多個表中訪問數(shù)據(jù)
????我們已討論了如何訪問單個表中的數(shù)據(jù)。從多個表中訪問數(shù)據(jù)也是可能的。從多個表中訪問數(shù)據(jù)稱為連接表(joining a table)。
1、??CROSS JOIN(笛卡爾積)
CROSS JOIN是簡單地、不加任何約束條件地把表組合。CROSS JOIN后結(jié)果的行數(shù)是連接前兩個表行數(shù)的乘積。如果對兩個分別有好幾千行的表進行連接,則結(jié)果是不可想象的。
2、??INNER JOIN
INNER JOIN是組合兩個表最常用的方法。INNER JOIN是基于一個判別式進行的,這個判別式稱為連接條件。連接條件和WHERE子句一起定義。連接條件由來自兩個表中的列組成,并使用一個比較條件來對列的值進行比較。通過比較的值包含在結(jié)果數(shù)據(jù)集中,以下是Inner JOIN的語法:
語法1:(ANSI 92)
Select <select_list>
FROM <table1> INNER JOIN <table2>
ON <table1>.<column name> = <table2>.<column name>
語法2:
Select <select_list>
FROM <table1>,<table2> WHERE <table1>.<column name> = <table2>.<column name>
在FROM 子句中可為表定義別名,并在任何地方都可用別名代替真名。
注意:如果作為連接條件的列中有空值,則空值不能和任何值匹配,因此結(jié)果中不包含有空值的行。
3、??Left Outer JOIN
在Inner JOIN中,只有在兩個表中匹配的行才能在結(jié)果數(shù)據(jù)集中。但在Left Outer JOIN中,所有左邊表中的行都出現(xiàn)在結(jié)果數(shù)據(jù)集中,如果左邊表中的某一行在右邊表中沒有匹配的行,則以空值取代右邊表中的值和它連接。
語法如下:(ANSI 92)
Select <select_list>
FROM <table1> LEFT OUTER JOIN <table2>
ON <table1>.<column name> = <table2>.<column name>
4、??Right Outer JOIN
Right Out JOIN和Left Outer JOIN相似,不同的是把右邊的表作為外部表(所有右邊表中的行包含在結(jié)果數(shù)據(jù)集中)。
語法如下:
Select <select_list>
FROM <table1> RIGHT OUTER JOIN <table2>
ON <table1>.<column name> = <table2>.<column name>
5、??Full Outer JOIN
在Full Outer JOIN中,所有兩個表中的行都包含在結(jié)果數(shù)據(jù)集中。
語法如下:
Select <select_list>
FROM <table1> FULL OUTER JOIN <table2>
ON <table1>.<column name> = <table2>.<column name>
Case語句
????當對不同條件產(chǎn)生不同的結(jié)果值時,可使用Case語句。
????Case語句計算所有定義的條件,并按條件是否為真而返回結(jié)果。
語法如下:
CASE [<input_expression>]
WHEN <when_expression> THEN <result_expression>
[ELSE <else_expression>]
END
Input_expression是任何有效的SQL Server表達式或布爾表達式。
When_expression是任何有效的SQL Server表達式或布爾表達式。這個表達式和Input_expression比較,如果Input_expression沒有定義,則When_expression應該是一個布爾表達式。
Result_expression是任何有效的SQL Server表達式。如果When_expression和Input_expression的比較返回TRUE(如果定義了Input_expression)或When_expression的值為TRUE,則計算表達式,并返回其結(jié)果。否則計算Else_expression中的表達式,并返回其結(jié)果。
例如:
SELECT au_fname,au_lname,
State=CASE state
??????????????WHEN ‘CA’ THEN ‘California’
??????????????WHEN ‘KS’ THEN ‘Kansas’
?????????END
FROM authors
UNION
???????UNION語句把兩個或多個查詢的結(jié)果組合成一個結(jié)果集。
???????語法如下:
???????SELECT <select_list>
???????FROM <table_list>
???????WHERE <join_condition>
???????UNION [ALL]
???????SELECT <table_list>
???????FROM <table_list>
???????WHERE <join_condition>
???????ALL關(guān)鍵字指定重復的數(shù)據(jù)也將包含在最終結(jié)果數(shù)據(jù)集中。如果需要,一個查詢中可以有許多UNION語句。所有Select_list應該有相同數(shù)目的列,且是相同或兼容的數(shù)據(jù)類型。
Go命令???????Go命令用來標志一個查詢批處理(query batch)的結(jié)束。查詢批處理是TSQL語句的集合,這些語句集合在一起執(zhí)行。Go與Osql或SQL Server Query Analyzer一起使用。
管理文本和圖像數(shù)據(jù)
???????文本和圖像數(shù)據(jù)類型列可以象其它列一樣包含在SELECT語句的Select_list中。通過SELECT語句檢索的最大文本大小由TEXTSIZE設(shè)置來控制。默認的TEXTSIZE的值是4096字節(jié),使用SET TEXTSIZE語句可重新設(shè)置。當前的TEXTSIZE設(shè)置的值存放在全局變量@@TEXTSIZE中。
???????另一種檢索文本和圖像數(shù)據(jù)的方法是通過TEXTPTR和READTEXT函數(shù)。TEXTPTR函數(shù)把列名字作為輸入?yún)?shù)并以二進制格式返回文本指針。
???????這個指針和被稱為偏移量的讀開始指針以及要讀的字節(jié)數(shù)量一起傳給READTEXT函數(shù),以檢索文本和圖像數(shù)據(jù)。
修改數(shù)據(jù)
???????TSQL也提供從數(shù)據(jù)庫插入、修改、刪除的命令。
插入
???????INSERT命令用來在表中插入數(shù)據(jù),語法如下:
???????INSERT [INTO] <table_name> [(column_list)] VALUES (value_list)
???????Value_list是和在Column_list中列相應的值。這些值可以是常量、TSQL變量或SQL Server內(nèi)部函數(shù)。值的順序應和column_list中列的順序相對應。如果沒有定義column_list,則值的順序應和表中列的順序?qū)?br />???????INSERT的Values_list也可通過SELECT語句或一個存儲過程來提供。語法如下:
???????INSERT [INTO] <table_name> [(column_list)]
???????SELECT <select_list> FROM <table_name>
???????INSERT [INTO] <table_name> [(column_list)]
???????EXECUTE <procedure_name>
???????這里的SELECT語句可包含多種連接。如果使用存儲過程,則存儲過程應返回能作為column_list的結(jié)果。
???????時間戳(timestamp,又稱時標)值不應被提供。同時,如果列的IDENTITY屬性被定義,則這一列的值也不能提供。這些值都由系統(tǒng)產(chǎn)生。如果列有默認值,則它們的值不被提供,而使用默認值。
修改
???????UPDATE語句用來修改行,語法如下:
???????UPDATE <table_name> SET <column_name> = <value> [,<column_name> = <value>_n]
???????WHERE <search_condition>]
???????Serach_condition是要修改的行應滿足的條件。沒有WHERE子句的UPDATE語句將修改表中的所有行。在UPDATE語句中也可使用連接。
刪除
???????DELETE語句用來從表中刪除行。語法如下:
???????DELETE [FROM] <table_name>
???????[WHERE <search_condition>]???????Serach_condition是刪除行要滿足的條件。一個無條件DELETE語句將刪除表中的所有行。在DELETE語句中也可使用連接。
使用SQL Server開發(fā)應用程序
編寫存儲過程與觸發(fā)器
???????存儲過程和觸發(fā)器是由用戶創(chuàng)建的、駐留在服務(wù)器的一組Transact SQL查詢語句。觸發(fā)器是系統(tǒng)在特定條件下執(zhí)行的。存儲過程能夠改善應用程序的性能。當客戶程序需要訪問數(shù)據(jù)時,一般要經(jīng)過5個步驟才能訪問到數(shù)據(jù):
1)??查詢語句被發(fā)送到服務(wù)器。
2)??服務(wù)器編譯SQL代碼。
3)??優(yōu)化產(chǎn)生查詢的執(zhí)行計劃。
4)??數(shù)據(jù)引擎執(zhí)行查詢。
5)??結(jié)果發(fā)回客戶程序。
存儲過程是在創(chuàng)建時編譯的,當存儲過程第一次執(zhí)行時,SQL Server產(chǎn)生查詢執(zhí)行計劃并將其存儲進來,以利于將來使用。當通過存儲過程發(fā)出一個請求時,上述的第2和第3步就沒有了,這能大大改善系統(tǒng)的性能。即使在第1步上也能提高性能。因為此時發(fā)送到服務(wù)器的語句只是一條存儲過程的EXECUTE語句,而不是龐大的、復雜的查詢。這種特性能降低網(wǎng)絡(luò)的流量。
除了性能方面的改善外,存儲過程還提供了方便地集中維護應用程序的功能。如果將查詢嵌入到應用程序中。而又需要對查詢進行改變,則應用程序需要重新編譯,并重新發(fā)布到所有的客戶端。而在存儲過程中,修改對用戶而言是透明的,它只需要在服務(wù)器上重新編譯存儲過程。
存儲過程還能提供安全機制,盡管用戶可能無權(quán)執(zhí)行存儲過程中的命令,但它卻可能有權(quán)執(zhí)行存儲過程本身。有時候,系統(tǒng)管理員不會給用戶以數(shù)據(jù)修改(UPDATE、INSERT和DELETE)的權(quán)力。創(chuàng)建的存儲過程卻能進行這些操作。當然用戶需要擁有執(zhí)行該存儲過程的權(quán)力。
建立存儲過程
???????存儲過程可以達到以下目的:
???????· 帶參數(shù)。
???????· 返回狀態(tài)值。
???????· 調(diào)用其它存儲過程。
???????· 在遠程服務(wù)器上執(zhí)行。
???????存儲過程在“sysobjects”系統(tǒng)表中有一個表項,其類型為“P”。存儲過程的文本存儲在“syscomments”系統(tǒng)表中。創(chuàng)建存儲過程需要使用Transact SQL命令CREATE PROCEDURE。
???????例如:
???????USE pubs
???????GO
???????
???????CREATE PROCEDURE ap_GetAuthorsForPublisher
???????AS
???????SELECT a.au_lname,a.au_fname
???????FROM authors a, titleauthor ta, titles t, publishers p
???????WHERE a.au_id = ta.Au_id
???????AND ta.Title_id = t.title_id
???????AND t.pub_id = p.pub_id
???????AND p.pub_name = ’New Moon Books’
???????GO
???????CREATE PROCEDURE語句的語法如下:
???????CREATE PROC[DURE] procedure_name [;number]
??????????????[@parameter_name ][OUTPUT] [,_n] ]
??????????????[WITH {RECOMPILE | ENCRYPTION}]
??????????????[FOR REPLICATION]
???????AS
???????Number是用來對相同名字的過程進行分組的整數(shù)。分組是將所有的過程通過drop procedure語句組合到一個分組中。
???????@parameter_name指定參數(shù)的名稱。
???????RECOMPILE表示每次執(zhí)行過程時都要進行編譯。
???????ENCRYPTION表示過程的文本在“syscomments”表中要加密。
???????FOR REPLICATION表示過程不能在提交服務(wù)器上執(zhí)行。
將參數(shù)傳遞給存儲過程
???????存儲過程能夠接受參數(shù)。
???????注意:過程的參數(shù)也可以是用戶定義的數(shù)據(jù)類型。
給參數(shù)一個缺省值
???????用戶還可以為存儲過程中的參數(shù)定義缺省值。當在執(zhí)行時沒有提供所需的參數(shù)時,系統(tǒng)就使用缺省值作為參數(shù)。如果既沒有定義缺省值,又沒有在執(zhí)行時提供參數(shù),則SQL Server就會返回一個錯誤。在存儲過程中定義缺省值,并使用一些邏輯檢測是否指定了參數(shù)從而采取相應的行動,這是一種很好的習慣。
???????例如:
???????USE pubs
???????GO
???????
???????CREATE PROCEDURE ap_GetAuthorsForPublisher
???????@PublisherName varchar(40) = ‘New Moon Books’
???????AS
???????SELECT a.au_lname,a.au_fname
???????FROM authors a, titleauthor ta, titles t, publishers p
???????WHERE a.au_id = ta.Au_id
???????AND ta.Title_id = t.title_id
???????AND t.pub_id = p.pub_id
???????AND p.pub_name = @PublisherName
???????GO
建立存儲過程體
???????存儲過程邏輯駐留在存儲過程體中。一個存儲過程體中可以包含任意條Transact SQL語句。下面的Transact SQL語句不能在任何存儲過程體中出現(xiàn):
???????· CREATE DEFAULT
???????· CREATE TRIGGER
???????· CREATE PROCEDURE
???????· CREATE VIEW
???????· CREATE RULE
1、??局部變量
局部變量保持存儲過程中間值。當一個值在存儲過程中需要多次,或者某個查詢的結(jié)果需要在隨后的查詢中使用時,需要使用局部變量。在這些情形下,值被存儲在局部變量中,并可用于將來的使用。本地變量的名稱以“@”符號開頭。變量的名稱可以包含字符和數(shù)值。局部變量在使用前需要進行類型聲明。對局部變量進行賦值需要使用SELECT語句。SELECT可以從一個表中檢索出值并將其賦給某個變量,也可以給變量賦一個常量值。一個簡單的SELECT語句可以給多個局部變量賦值。
例如:
DECLARE @var1 integer, @var2 varchar(20)
SELECT @var1 = 32,
???????????@var2 = ‘MyAge’
如果從SELECT查詢中沒有返回任何數(shù)據(jù),而SELECT又要將數(shù)據(jù)的值賦予局部變量,則該局部變量的值將不會發(fā)生改變。
2、??條件詞句
存儲過程中提供的條件語句包括:
· IF……ELSE語句。
· WHILE語句。
1)??IF……ELSE語句。在該語句中包含三個部分:布爾運算表達式,IF語句塊和ELSE語句塊。語法如下:
IF (boolen_expr)
??{statements}
ELSE
??{statements}
在IF或ELSE語句塊中可以有多條語句,這種情形下,需要語句BEGIN和END來標志語句塊。
2)??WHILE語句。WHILE語句用于處理直到某個條件為TRUE前重復執(zhí)行的語句。語法如下:
WHILE (boolen_expr)
??BEGIN
??statement(s)
BREAK
Statement(s)
CONTINUE
??????????????END
????????????BEGIN和END語句標志循環(huán)體。BREAK語句結(jié)束循環(huán)的執(zhí)行(即走到END語句之后)。CONTINUE語句將控制處理過程回到循環(huán)的開始處(即BEGIN語句的右邊)。
????????????注意:如果有兩個或多個WHILE循環(huán)被嵌套,則內(nèi)部的BREAK退出的是次外層的循環(huán)。內(nèi)部循環(huán)結(jié)束之后的所有語句在內(nèi)部循環(huán)執(zhí)行之后才能繼續(xù)執(zhí)行。
3、??GOTO語句
在存儲過程的執(zhí)行中,語句是順序執(zhí)行的。GOTO語句則是用來打破這種語句執(zhí)行的順序,它立即跳到某條語句上執(zhí)行,而這條語句往往不緊跟在前一語句之后。GOTO語句與一個標志(Label)一起使用,該標志用來標識一條語句。
例如:
USE pubs
GO
DECLARE @num int
SELECT
IF @num = 0
???????GOTO Err
ELSE
???????BEGIN
???????PRINT ‘a(chǎn)uthors found’
???????SELECT * FROM authors
???????GOTO Last
???????END
Err: PRINT ‘no authors found’
Last: PRINT ‘Finish execution’
GO
4、??RETURN語句
RETURN語句用于無條件的退出存儲過程。RETURN之后的任何語句都不再執(zhí)行。RETURN語句可以給調(diào)用語句返回一個值,但不能返回NULL值。SQL Server經(jīng)常為存儲過程返回一個狀態(tài)值。如果成功地執(zhí)行,則返回一個0,如果出現(xiàn)了錯誤,則返回一個為負數(shù)的錯誤碼。
存儲過程返回的錯誤碼
值
說????????明
值
說????????明
0
過程執(zhí)行成功
-8
發(fā)生了非致命的內(nèi)部問題
-1
漏掉了對象
-9
達到了系統(tǒng)極限
-2
發(fā)生了數(shù)據(jù)類型錯誤
-10
發(fā)生了致命的內(nèi)部不一致錯誤
-3
該處理被選擇成了死鎖的犧牲者
-11
發(fā)生了致命的內(nèi)部不一致錯誤
-4
發(fā)生了權(quán)限錯誤
-12
表或索引被破壞
-5
發(fā)生了語法錯誤
-13
數(shù)據(jù)庫被破壞
-6
發(fā)生了混雜的用戶錯誤
-14
發(fā)生了硬件錯誤
-7
資源錯誤,如空間不夠等
5、??使用游標(CURSOR)在需要一行一行處理時,游標十分有用。游標可以打開一個結(jié)果集合(按照指定的標準選擇的行),并提供在結(jié)果集中一行一行處理的功能。基于游標的類型,可以對其進行回滾或者前進。在使用游標時需要5個步驟:
i.??????????????聲明游標
在這一步中,需要指定游標的屬性和根據(jù)要求產(chǎn)生的結(jié)果集。有兩種方法可以指定一個游標。
形式1??(ANSI 92)
DECLARE cursor_name [INSENSITIVE] [SCROLL] CURSOR
FOR select_statement
[FOR {READ ONLY | UPDATE ][OF column_list]}]
形式2
DECLARE cursor_name CURSOR
[LOCAL | GLOBAL]
[FORWARD_ONLY | SCROLL]
[STATIC | KEYSET | DYNAMIC]
[READ_ONLY | SCROLL_LOCKS | OPTIMISTIC]
FOR select_statement
[FOR {READ ONLY | UPDATE ][OF column_list]}]
INSENSITIVE關(guān)鍵字指明要為檢索到的結(jié)果集建立一個臨時拷貝,以后的數(shù)據(jù)從這個臨時拷貝中獲取。如果在后來游標處理的過程中,原有基表中數(shù)據(jù)發(fā)生了改變,那么它們對于該游標而言是不可見的。這種不敏感的游標不允許數(shù)據(jù)更改。
SCROLL關(guān)鍵字指明游標可以在任意方向上滾動。所有的fetch選項(first、last、next、relative、absolute)都可以在游標中使用。如果忽略該選項,則游標只能向前滾動(next)。
Select_statement指明SQL語句建立的結(jié)果集。Transact SQL語句COMPUTE、COMPUTE BY、FOR BROWSE和INTO在游標聲明的選擇語句中不允許使用。
READ ONLY指明在游標結(jié)果集中不允許進行數(shù)據(jù)修改。
UPDATE關(guān)鍵字指明游標的結(jié)果集可以修改。
OF column_list指明結(jié)果集中可以進行修改的列。缺省情況下(使用UPDATE關(guān)鍵字),所有的列都可進行修改。
LOCAL關(guān)鍵字指明游標是局部的,它只能在它所聲明的過程中使用。
GLOBAL關(guān)鍵字使得游標對于整個連接全局可見。全局的游標在連接激活的任何時候都是可用的。只有當連接結(jié)束時,游標才不再可用。
FORWARD_ONLY指明游標只能向前滾動。
STATIC的游標與INSENSITIVE的游標是相同的。
KEYSET指明選取的行的順序。SQL Server將從結(jié)果集中創(chuàng)建一個臨時關(guān)鍵字集。如果對數(shù)據(jù)庫的非關(guān)鍵字列進行了修改,則它們對游標是可見的。因為是固定的關(guān)鍵字集合,所以對關(guān)鍵字列進行修改或新插入列是不可見的。
DYNAMIC指明游標將反映所有對結(jié)果集的修改。
SCROLL_LOCK是為了保證游標操作的成功,而對修改或刪除加鎖。
OPTIMISTIC指明哪些通過游標進行的修改或者刪除將不會成功。
注意:
· 如果在SELECT語句中使用了DISTINCT、UNION、GROUP BY語句,且在選擇中包含了聚合表達式,則游標自動為INSENSITIVE的游標。
· 如果基表沒有唯一的索引,則游標創(chuàng)建成INSENSITIVE的游標。
· 如果SELECT語句包含了ORDER BY,而被ORDER BY的列并非唯一的行標識,則DYNAMIC游標將轉(zhuǎn)換成KEYSET游標。如果KEYSET游標不能打開,則將轉(zhuǎn)換成INSENSITIVE游標。使用SQL ANSI-92語法定義的游標同樣如此,只是沒有INSENSITIVE關(guān)鍵字而已。
???????????????????????ii.??????????????打開游標
打開游標就是創(chuàng)建結(jié)果集。游標通過DECLARE語句定義,但其實際的執(zhí)行是通過OPEN語句。語法如下:
OPEN { { [GLOBAL] cursor_name } | cursor_variable_name}
GLOBAL指明一個全局游標。
Cursor_name是被打開的游標的名稱。
Cursor_variable_name是所引用游標的變量名。該變量應該為游標類型。
在游標被打開之后,系統(tǒng)變量@@cursor_rows可以用來檢測結(jié)果集的行數(shù)。@@cursor_rows為負數(shù)時,表示游標正在被異步遷移,其絕對值(如果@@cursor_rows為-5,則絕對值為5)為當前結(jié)果集的行數(shù)。異步游標使用戶在游標被完全遷移時仍然能夠訪問游標的結(jié)果。
??????????????????????iii.??????????????從游標中取值
在從游標中取值的過程中,可以在結(jié)果集中的每一行上來回移動和處理。如果游標定義成了可滾動的(在聲明時使用SCROLL關(guān)鍵字),則任何時候都可取出結(jié)果集中的任意行。對于非滾動的游標,只能對當前行的下一行實施取操作。結(jié)果集可以取到局部變量中。Fetch命令的語法如下:
FETCH [NEXT | PRIOR| FIRST | LAST | ABSOLUTE {n | @nvar} | RELATIVE {n | @nvar}]
FROM [GLOBAL] cursor_name} | cursor_variable_name}
[INTO @variable_name ][,……n]]
NEXT指明從當前行的下一行取值。
PRIOR指明從當前行的前一行取值。
FIRST是結(jié)果集的第一行。
LAST是結(jié)果集的最后一行。
ABSOLUTE n表示結(jié)果集中的第n行,該行數(shù)同樣可以通過一個局部變量傳播。行號從0開始,所以n為0時不能得到任何行。
RELATIVE n表示要取出的行在當前行的前n行或后n行的位置上。如果該值為正數(shù),則要取出的行在當前行前n行的位置上,如果該值為負數(shù),則返回當前行的后n行。
INTO @cursor_variable_name表示游標列值存儲的地方的變量列表。該列表中的變量數(shù)應該與DECLARE語句中選擇語句所使用的變量數(shù)相同。變量的數(shù)據(jù)類型也應該與被選擇列的數(shù)據(jù)類型相同。直到下一次使用FETCH語句之前,變量中的值都會一直保持。
每一次FETCH的執(zhí)行都存儲在系統(tǒng)變量@@fetch_status中。如果FETCH成功,則@@fetch_status被設(shè)置成0。@@fetch_status為-1表示已經(jīng)到達了結(jié)果集的一部分(例如,在游標被打開之后,基表中的行被刪除)。@@fetch_status可以用來構(gòu)造游標處理的循環(huán)。
例如:
DECLARE @iname char(20), @fname char(20)
OPEN author_cur
FETCH FIRST FROM author_cur INTO @iname, @fname
WHILE @@fetch_status = 0
BEGIN
IF @fname = ‘Albert’
PRINT “Found Albert Ringer”
ELSE
Print “Other Ringer”
FETCH NEXT FROM author_cur INTO @iname, @fname
END
?????????????????????iv.??????????????關(guān)閉游標
CLOSE語句用來關(guān)閉游標并釋放結(jié)果集。游標關(guān)閉之后,不能再執(zhí)行FETCH操作。如果還需要使用FETCH語句,則要重新打開游標。語法如下:
CLOSE [GLOBAL] cursor_name | cursor_variable_name
???????????????????????v.??????????????釋放游標
游標使用不再需要之后,要釋放游標。DEALLOCATE語句釋放數(shù)據(jù)結(jié)構(gòu)和游標所加的鎖。語法如下:
DEALLOCATE [GLOBAL] cursor_name | cursor_variable_name
???????下面給出游標的一個完整的例子:
???????USE master
???????GO
???????CREATE PROCEDURE sp_BuildIndexes
???????AS
???????DECLARE @TableName sysname, @msg varchar(100), @cmd varchar(100)
???????DECLARE table_cur CURSOR FOR
???????SELECT name FROM sysobjects WHERE type=’u’
???????OPEN table_cur
???????FETCH NEXT FROM table_cur INTO @TableName
???????
???????WHILE @@fetch_status = 0
???????BEGIN
??????????????IF @@fetch_status = -2
?????????????????????CONTINUE
??????????????SELECT @msg = “Building indexes for table”+@TableName+”…”
??????????????PRINT @msg
??????????????SELECT @cmd = “DBCC DBREINDEX (‘”+@TableName+”')”
??????????????EXEC (@cmd)
??????????????PRINT “????“
??????????????FETCH NEXT FROM table_cur INTO @TableName
???????END
???????DEALLOCATE table_cur
???????GO
???????下面的腳本將為PUBS數(shù)據(jù)庫執(zhí)行sp_BuildIndexes
???????USE pubs
???????GO
???????EXEC ap_BuildIndexes
???????注意:上面也是創(chuàng)建用戶定義的系統(tǒng)存儲過程的示例。
使用臨時表
???????臨時表是在TempDB中創(chuàng)建的表。臨時表的名稱都以“#”開頭。臨時表的范圍為創(chuàng)建臨時表的連接。因為,臨時表不能在兩個連接之間共享,一旦連接關(guān)閉,臨時表就會被丟棄。如果臨時表被創(chuàng)建于存儲過程之中,則臨時表的范圍在存儲過程之中,或者被該存儲過程調(diào)用的任何存儲過程之中。如果需要在連接之間共享臨時表,則需要使用全局的臨時表。全局的臨時表以“##”符號開頭,它將一直存在于數(shù)據(jù)庫中,直到SQL Server重新啟動。一旦這類臨時表創(chuàng)建之后,所有的用戶都可以訪問到。在臨時表上不能明確地指明權(quán)限。???????臨時表提供了存儲中間結(jié)果的能力。有時候,臨時表還能通過將一個復雜的查詢分解成兩個查詢而獲得性能的改善。這可以通過首先將第一個查詢的結(jié)果存在臨時表中,然后在第二個查詢中使用臨時表來實現(xiàn)。當一個大表中的某個子集在一個在座過程中使用多次時,建議使用臨時表。在這種情況下,在臨時表中保持數(shù)據(jù)的子集,以在隨后的連接中使用,這樣能大大改善性能。還可以在臨時表中創(chuàng)建索引。
存儲過程中返回結(jié)果
???????從存儲過程中返回結(jié)果有三種方式:
1、??返回結(jié)果集
這是客戶端應用程序返回結(jié)果的最通用的方法。結(jié)果集是通過使用SELECT語句選擇數(shù)據(jù)產(chǎn)生的。結(jié)果集可以從永久表、臨時表或局部變量中產(chǎn)生。將結(jié)果返回到另一個存儲過程不是一種有效的方法。存儲過程不能訪問另一個存儲過程建立的結(jié)果集。
例如從永久表中返回結(jié)果集:
USE pubs
GO
CREATE PROCEDURE ap_CreateResultFromPermtable
AS
SELECT au_iname FROM authors
GO
例如從局部變量中創(chuàng)建結(jié)果集:
USE pubs
GO
CREATE PROCEDURE ap_CreateResultFromVariable
AS
DECLARE @au_iname char(20)
SELECT @au_iname = au_iname FROM authors
WHERE au_id = ‘172-32-1176’
SELECT @au_id
GO
2、??設(shè)置OUTPUT參數(shù)的值
輸出參數(shù)經(jīng)常用來從存儲過程中檢索出結(jié)果。如果某個參數(shù)在傳輸?shù)酱鎯^程中時被定義成OUTPUT,則對該參數(shù)的任何修改在退出存儲之后仍然有效。
例如:
USE pubs
GO
CREATE PROCEDURE ap_SetOutputVar @count integer OUTPUT
AS
SELECT @count = count(*) FROM authors
GO
從輸出參數(shù)中檢索出值:
USE pubs
GO
CREATE PROCEDURE ap_GetOutputVar
AS
DECLARE @num integer
EXECUTE ap_SetOutputVar @num OUTPUT
PRINT “the count is”+convert(char,@num)
GO
· 將游標使用成OUTPUT參數(shù)。游標可以使用OUTPUT(輸出)參數(shù),但不能使用成輸入?yún)?shù)。也就是說,游標可以作為結(jié)果返回,但卻不能傳輸?shù)竭^程中去。當游標被用作參數(shù)時,需要限定其為OUTPUT和VARYING。VARYING關(guān)鍵字指出該結(jié)果集要用來支持輸出參數(shù)。這樣就提供了將結(jié)果集返回到調(diào)用過程的能力。
例如:
USE pubs
GO
CREATE PROCEDURE GetTitleCount @count_cursor CURSOR VARYING OUTPUT
AS
SET @count_cursor = CURSOR
FOR
SELECT au_id,count(*)
FROM titleauthors
GROUP BY au_id
OPEN @count_cursor
GO
3、??通過RETURN參數(shù)返回狀態(tài)
這是一種從存儲過程返回錯誤碼的方法。存儲過程總是返回一個狀態(tài)值,用戶也可以使用RETURN語句返回自己的狀態(tài)。
例如:
USE pubs
GO
CREATE PROCEDURE ap_SetReturnStatus
AS
DECLARE @count integer
SELECT @count = count(*) FROM authors
IF @count = 0
RETURN(1)
ELSE
RETURN (0)
GO
例如檢索出返回的狀態(tài):
USE pubs
GO
CREATE PROCEDURE ap_GetReturnStatus
AS
DECLARE @status integer
EXECUTE @status = ap_SetReturnStatus
IF @status = 1
PRINT “No rows found”
ELSE
PRINT “successful”
GO
在存儲過程中進行錯誤處理
???????如同其它程序一樣,在存儲過程中進行錯誤處理是非常重要的。系統(tǒng)變更@@error在執(zhí)行每一個Transact SQL語句之后都會得到一個值。對于成功的執(zhí)行,@@error的值為0,如果出現(xiàn)錯誤,則@@error中將包含錯誤信息。@@error系統(tǒng)變量對存儲過程的錯誤處理是非常重要的。
???????注意:為了防止錯誤,@@error所能設(shè)置的值在sysmessages表的“error”中反映了出來。
在存儲過程中的錯誤有兩種類型:
1、????數(shù)據(jù)庫相關(guān)的錯誤
這些錯誤是由數(shù)據(jù)庫的不一致性引起的,系統(tǒng)使用非0的@@error值表示特定的數(shù)據(jù)庫問題。在Transact SQL執(zhí)行之后,可以通過@@error獲得所出現(xiàn)的錯誤。如果發(fā)現(xiàn)@@error不為0,則必須采取必要的行動,大多數(shù)情況下,存儲將不再繼續(xù)進行處理而返回。下面的示例展示了典型的獲取數(shù)據(jù)庫錯誤的方法。該過程將錯誤代碼放置到輸出變量中,這樣,調(diào)用程序就能夠訪問到。
USE pubs
GO
CREATE PROCEDURE ap_TrapDatabaseError @return_code integer OUTPUT
AS
UPDATE authors SET au_iname = “Jackson”
WHERE au_iname = “Smith”
IF @@error <> 0
BEGIN
???????SELECT @return_code = @@error
???????RETURN
END
ELSE
???????@return_code = 0
GO
2、????業(yè)務(wù)邏輯錯誤
這些錯誤是由于違反了業(yè)務(wù)規(guī)則而引起的。要獲取這些錯誤,首先需要定義業(yè)務(wù)規(guī)則,基于這些規(guī)則,需要在存儲過程中增加必要的錯誤檢測代碼。人們經(jīng)常使用RAISERROR語句通報這些錯誤。RAISERROR提供了返回用戶定義錯誤及將@@error變量設(shè)置成用戶定義錯誤號的能力。錯誤消息可以被動態(tài)地建立,或者基于錯誤號從“sysmessages”表中檢索到。一旦出現(xiàn)了錯誤,錯誤就會以一種服務(wù)器錯誤消息的方式返回到客戶機。下面是RAISERROR命令的語法:
RAISERROR (msg_id | msg_str, severity, state
[, argument ][,…n]])
[WITH options]
Msg_id指明用戶定義消息的id,該消息存儲在“sysmessages”系統(tǒng)表中。
Msg_str用于動態(tài)創(chuàng)建消息的消息字符串。這與C語言中的“printf”非常相似。
Severity定義用戶賦值的錯誤消息嚴重程度。
State是從1到127的任意整數(shù)值,它表示錯誤的調(diào)用狀態(tài)信息。負數(shù)的state值將缺省為1。
OPTIONS指明錯誤的定制選項。OPTIONS的有效值如下:
1)??LOG。
將錯誤記錄到服務(wù)器錯誤日志和NT事件日志中。該選項需要消息帶有從19到25的嚴重程度。而只有系統(tǒng)管理員才能發(fā)出這種消息。
2)??NOWAIT。
將消息立即發(fā)送到客戶端服務(wù)器。
3)??SETERROR。
不管其嚴重級別如何,將@@error的值設(shè)置為msg_id或5000。
遠程過程調(diào)用
???????SQL Server提供了調(diào)用駐留在不同服務(wù)器上的存儲過程的能力。調(diào)用這樣的存儲過程稱謂遠程存儲過程調(diào)用。為了使得調(diào)用能從一個SQL Server轉(zhuǎn)移到另一個服務(wù)器,兩個服務(wù)器應該相互定義成對方的有效遠程服務(wù)器。
???????設(shè)置遠程服務(wù)器的配置:
???????· 擴展某個服務(wù)器的組。
???????· 右擊該服務(wù)器并點擊“Properties”。
???????· 設(shè)置選項“Allow other SQL Servers to connect remotely to this SQL server via RPC”。
???????· 設(shè)置“Query time out”選項的值,該值指定從一個查詢處理返回所能等待的秒數(shù)。缺省值為0,表示允許無限的等待時間。
???????· 設(shè)置完成配置選項之后,點擊“OK”。
???????· 重新啟動服務(wù)器之后,修改將會生效。
???????· 在另一臺遠程服務(wù)器上重復相同的步驟。
???????調(diào)用遠程存儲過程需要指明服務(wù)器的名稱,后帶數(shù)據(jù)庫的名稱和擁有者的名稱。下面是在不同的服務(wù)器(Server2)上調(diào)用一個存儲過程的示例。
Exec server2.pubs.dbo.myproc
豆豆的后話:
???????這里只是粗淺的介紹了SQL Server常用的知識,對象也是基于SQL Server數(shù)據(jù)庫編寫應用程序的編程人員,而非數(shù)據(jù)庫管理者。但對于應用程序編程者,了解數(shù)據(jù)庫的管理也是非常有用的。建議在以后的時間自行去了解數(shù)據(jù)庫的管理,這對于優(yōu)化程序也是相當有用的。
————————全文完—————————
轉(zhuǎn)載于:https://www.cnblogs.com/cnLiou/archive/2005/08/13/213866.html
創(chuàng)作挑戰(zhàn)賽新人創(chuàng)作獎勵來咯,堅持創(chuàng)作打卡瓜分現(xiàn)金大獎總結(jié)
以上是生活随笔為你收集整理的SQL SERVER7应用的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 小程序发布上线流程_家居小程序傻瓜式制作
- 下一篇: 生成word_Word生成员工信息表,每