Transact-SQL具體可以參閱《Transact-SQL參考》(tsql.hlp)(簡寫《T-SQL》) 建意: 在寫SQL Script時最好能將資料操作SQL的保留字用大寫註:此處文法格式只是常用格式,並不是SQL標準格式,標準格式請參閱《T-SQL》
以下所用的程式碼都使用VB6.0代碼,在例子中的SQL無實際意義 選擇SELECTSELECT 可以選擇指定的資料列如:SELECT * FROM sysobjectsSELECT [name] FROM syscolumns當在SQL中存在系統保留字時應用“[]”引起,或在SQL中存在特殊字元也應用“[]”引起,如: SELECT [Object Name] FROM Objects在使用別名時也應注意以上原則,別名使用可以用以下兩種方法: Column_name AS alias Column_name alias中間的AS可以省略在SELECT中可以使用條件選擇文法,參見下面的“條件” 如: SELECT [name],xtype,CASE WHEN xtype=’U’ THEN ‘使用者表’ ELSE CASE WHEN xtype=’S’ THEN ‘系統資料表’ END END AS 類型 FROM sysobjects返回表:
| name |
xtype |
類型 |
| syscolumns |
S |
系統資料表 |
| tabledefine |
U |
使用者表 |
將兩個查詢合成單獨的返回表:用UNION關鍵字如SELECT A,B FROM Table1 UNOIN SELECT C,D FROM Table2說明: 在使用UNION時,若無ALL參數則預設將過慮相同的記錄, 如:
| Table1 |
|
Table2 |
| ID |
TF1 |
VALUE1 |
|
ID |
TF2 |
VALUE2 |
| 1 |
A |
10 |
|
5 |
A |
10 |
| 5 |
B |
20 |
|
6 |
D |
21 |
| 2 |
A |
30 |
|
3 |
C |
31 |
| 3 |
C |
40 |
|
1 |
B |
41 |
SELECT TF1,VALUE1 FROM Table1 UNION SELECT TF2,VALUE2 FROM Table2
返回表:
| TF1 |
VALUE1 |
| A |
10 |
| B |
20 |
| A |
30 |
| C |
40 |
| D |
21 |
| C |
31 |
| B |
41 |
其中可以看出少了一個”TF2=A ,VALUE2=10”的記錄 但用以下查詢時 SELECT TF1,VALUE1 FROM Table1 UNION ALL SELECT TF2,VALUE2 FROM Table2 返回表:
| TF1 |
VALUE1 |
| A |
10 |
| B |
20 |
| A |
30 |
| C |
40 |
| A |
10 |
| D |
21 |
| C |
31 |
| B |
41 |
剛此查詢將返回所有記錄 此問題可能會出現在報表統計上,如一個員工在不同日期內做了相同的產品與資料,但在使用非ALL方式進行合計時將會少合計一條記錄 與INTO聯用SELECT …. INTO B FROM A可以將A 表的指定資料存入B表中應用類型:備份資料表: SELECT * INTO Table1_bak FROM Table1 建立新表 SELECT * INTO New_Table1 FROM Table1 WHERE 1<>1 SELECT TOP 0 * INTO New_Table1 FROM Table1 儲存查詢結果 SELECT Field1,Field2 INTO Result FROM Table1 WHERE ID>1000 建立新表並在新表中加入自動序號 一表有些表需要一個自動編號列來區別於各行 SELECT IDENTITY (INT,1,1) AS AutoId,* INTO new_Table1 FROM Table1 其中IDENTITY函數說明: 格式: IDENTITY (<datatype> [seed,increment]) 參數說明: Datatype:資料類型,視記錄數定類型,一般可以定INT型,具體可以參考SQL的極限參數 Seed:開始數值,即開始的基數,預設為1 Increment:增量,步長即資料間的間隔,預設為1 上面的SQL即表示,自動編號從1開始並每行加1返回的表為:
| AutoId |
Field1 |
Field2 |
| 1 |
Hello |
Joy |
| 2 |
Hello |
Tom |
| 3 |
Hi |
Lily |
| 4 |
Hello |
Lily |
註: IDENTITY還可以在建立表時設定 格式: IDENTITY ([seed, increment]) 如: 建立表 CREATE TABLE Table1 ( AutoId int IDENTITY(1,1), 或 autoid int identity Field1 nvarchar(30), Field2 nvarchar(30)) 修改表 ALTER TABLE Table1 ADD AutoId int IDENTITY (1,1) 在進行資料插入時應注意IDENTITY_INSERT這個屬性的設定 當 SET IDENTITY_INSERT <table> ON 時,則不能進行隱式插入 如: SET IDENTITY_INSERT Table1 ON INSERT INTO Table1 SELECT (‘r1c1’,’r1c2’) --這樣就會出錯 必需使用: INSERT INTO Table1 SELECT (1,’R1C1’,’R1C2’) 只能在SET IDENTITY_INSERT <table> OFF 時才允許隱式插入 如: SET IDENTITY_INSERT Table OFF必需使用: INSERT INTO Table1 SELECT (‘r1c1’,’r1c2’) 否則 INSERT INTO Table1 SELECT (1,’R1C1’,’R1C2’) --這樣就會出錯 在使用隱式插入後可以用@@IDENTITY這個系統值來返回插入行的編號 INSERT INTO Table1 SELECT(‘R1C1’,’R1C2’) 返回表:
| AutoID |
Field1 |
Field2 |
| 1 |
R1C1 |
R1C2 |
SELECT @@IDENTITY 傳回值: 1 在應用程式中可以用以下方法做: set recs=cnn.execute(“INSERT INTO Table1 SELECT(‘R1C1’,’R1C2’)”) recordnum=cnn.execute(“SELECT @@IDENTITY”).fields(0).value 以上語句執行後recordnum的值將設定為最後一個自動編號 關聯 用例:
| Table1 |
|
Table2 |
| ID |
TF1 |
VALUE1 |
|
ID |
TF2 |
VALUE2 |
| 1 |
TFI1-1 |
10 |
|
5 |
TFI2-1 |
11 |
| 5 |
TFI1-2 |
20 |
|
6 |
TFI2-2 |
21 |
| 2 |
TFI1-3 |
30 |
|
3 |
TFI2-3 |
31 |
| 3 |
TFI1-4 |
40 |
|
1 |
TFI2-4 |
41 |
Table2INNER JOIN只顯示兩表一一對應的記錄SELECT * FROM Table1 INNER JOIN Table2 ON Table1.ID=Table2.ID ORDER BY Table1.ID返回表:
| ID |
TF1 |
VALUE1 |
ID |
TF2 |
VALUE2 |
| 1 |
TFI1-1 |
10 |
1 |
TFI2-4 |
41 |
| 3 |
TFI1-4 |
40 |
3 |
TFI2-3 |
31 |
| 5 |
TFI1-2 |
20 |
5 |
TFI2-1 |
11 |
LEFT JOIN(LEFT OUTER JOIN)顯示左表所有記錄與右表對應左表的記錄,當在右表中無記錄,則右表相應欄位用NULL填充SELECT * FROM Table1 LEFT JOIN Table2 ON Table1.ID=Table2.ID ORDER BY Table1.ID返回表:
| ID |
TF1 |
VALUE1 |
ID |
TF2 |
VALUE2 |
| 1 |
TFI1-1 |
10 |
1 |
TFI2-4 |
41 |
| 2 |
TFI1-3 |
30 |
NULL |
NULL |
NULL |
| 3 |
TFI1-4 |
40 |
3 |
TFI2-3 |
31 |
| 5 |
TFI1-2 |
20 |
5 |
TFI2-1 |
11 |
RIGHT JOIN(LEFT OUTER JOIN)顯示右表所有記錄與左表對應右表的記錄,當在左表中無記錄,則左表相應欄位用NULL填充SELECT * FROM Table1 LEFT JOIN Table2 ON Table1.ID=Table2.ID ORDER BY Table1.ID返回表:
| ID |
TF1 |
VALUE1 |
ID |
TF2 |
VALUE2 |
| NULL |
NULL |
NULL |
6 |
TFI2-2 |
21 |
| 1 |
TFI1-1 |
10 |
1 |
TFI2-4 |
41 |
| 3 |
TFI1-4 |
40 |
3 |
TFI2-3 |
31 |
| 5 |
TFI1-2 |
20 |
5 |
TFI2-1 |
11 |
FULL JOIN(FULL OUTER JOIN)顯示左右兩表所有記錄,當左表無記錄,則左表相應欄位用NULL填充,當右表無記錄則右表相關欄位用NULL填充SELECT * FROM Table1 LEFT JOIN Table2 ON Table1.ID=Table2.ID ORDER BY Table1.ID返回表:
| ID |
TF1 |
VALUE1 |
ID |
TF2 |
VALUE2 |
| 1 |
TFI1-1 |
10 |
1 |
TFI2-4 |
41 |
| 2 |
TFI1-3 |
30 |
NULL |
NULL |
NULL |
| 3 |
TFI1-4 |
40 |
3 |
TFI2-3 |
31 |
| 5 |
TFI1-2 |
20 |
5 |
TFI2-1 |
11 |
| NULL |
NULL |
NULL |
6 |
TFI2-2 |
21 |
說明: 在進行多級關聯的時候應該採用就近關聯原則如: SELECT * FROM Table1 INNER JOIN Table2 INNER JOIN Table2-1 ON Table2.ID=Table2-1.ID ON Table1.ID=Table2.ID即Table2與Table2-1關聯 Table1與Table2關聯建意: 在寫此類關聯時,最好將基語句格式結構化 如: SELECT * FROM Table1 INNER JOIN Table2 INNER JOIN Table2-1 ON Table2.ID=Table2-1.ID ON Table1.ID=Table2.ID WHERE ID IN (1,2,3)註: 在寫完查詢語句後,可以由“企業管理器”進行SQL語句的格式化,但這一過程出來的語句一定要進行測試,因為在他自動格式化時可能會把某些複雜的關係搞錯 分組GROUP BY(沒什麼好說!!)如: SELECT A,B,SUM(D) FROM Table1 GROUP BY A,B ORDER BY A註: 在進行GROUP BY 時應該注意GROUP BY 中欄位的使用, 只要在同一查詢語句中則所有未進行驟合操作的欄位都需要被GROUP, 如上面的SQL中,欄位A,與B都未被驟合,並欄位A被排序,而欄位D被驟合函數SUM進行匯總統計 因此欄位A,B需要被GROUP 而D則不用如: SELECT A,B,SUM(D) FROM Table1 GROUP BY A,B,C ORDER BY C在此查詢中,雖然欄位C沒有被選擇,但他被ORDER因此欄位C也應該在GROUP的欄位中如: SELECT A,B,SUM(D) FROM Table1 WHERE A IN (SELECT D FROM Table1 T1 WHERE NOT C IS NULL) GROUP BY A,B,C ORDER BY C 在此查詢中欄位A,B為選擇欄位,欄位C為排序欄位,但欄位D雖然也在同一張表Table1中,但他在子查詢中因此不用進行對D的GROUP 若要對彙總結果進行篩選則應該使用HAVING關鍵字,而不是WHERE關鍵字, 如: SELECT A,B,SUM(D) FROM Table1 WHERE COUNT(*)>2 GROUP BY A,B ---這樣將會出錯,因為COUNT為一個彙總函式,在WHERE子句中不能對彙總函式進行篩選 應改為: SELECT A,B,SUM(D) FROM Table1 GROUP BY A,B HAVING COUNT(*)>2 應用GROUP可以進行分類統計相關的關鍵字為CUBE,ROLLUP但不建意使用這兩個關鍵字,在一般情況下,如果程式中的GRID有分類匯總功能,那相應的速度會比使用這兩個關鍵字要快,與這兩個關鍵字一起使用的彙總函式為GROUPING(),即當進行項目分類匯總時GROUPING()將會返回1,反之則為0,為可以寫統計標題時提供參考,具體說明請參見《T-SQL》 條件CASE WHEN此組關鍵字的功能可以代替IF…THEN….ELSE或SELECT CASE文法結構:CASE [expression] WHEN <condition> THEN result [ELSE else_result ] END在查詢中使用此語句時應盡量在END後加別名, 如: SELECT [name],xtype,CASE WHEN xtype=’U’ THEN ‘使用者表’ ELSE CASE WHEN xtype=’S’ THEN ‘系統資料表’ END END AS 類型 FROM sysobjects
返回表:
| name |
xtype |
類型 |
| syscolumns |
S |
系統資料表 |
| tabledefine |
U |
使用者表 |
用此語句與SELECT用UNION聯用能做行列換位 過程性語句應用 變數定義 在SQL中使用者變數是以@打頭的字串,系統變數用@@打頭如: @i @tmpStr定義方法: Declare @i int Declare @tmpStr nvarchar(30) 在完成變數定義後最好進行初始設定,如Set @i=0Set @tmpStr=’’或Select @i=0,@tmpStr=’’ 在SQL中對變數的賦值應用SET或SELECT進行 遊標定義遊標,可以將查詢結果返回為遊標類型定義方法:Declare cursor <CurName> For <SQL SCRIPT>如:declare cursor GetName for SELECT [name] FROM sysobjects遊標使用方法:開啟遊標:Open <CurName>如:open GetName檢索遊標:Fetch [NEXT | PRIOR | FIRST | LAST] form <CurName> [into <valuename>…]如:Fetch next from GetName into @tmpName當取值成功後,相應記錄值會填充在@tmpName變數中,並@@FETCH_STATUS變數置為0,若失敗則@@FETCH_STATUS變數為-1關閉遊標在使用完遊標後關閉他,以便其他進程使用此遊標CLOSE <curname>如: Close GetName刪除遊標在使用完遊標後,如不再需要應該刪除已使用遊標,DEALLOCATE <curname>如: Deallocate GetName