## 一、特殊指令與函式
### 1. 執行動態生成SQL指令
- sp_executesql
可以將字串當作SQL語言並進行執行的系統內建函式,主要用以執行可重複使用多次的 Transact-SQL 語句或批次,或動態建立的語句。 Transact-SQL 語句或批次可以包含內嵌參數。
SQL範例:
``` SQL
DECLARE @sql NVARCHAR(max);
DECLARE @Name NVARCHAR(50) = 'Jacky Lin';
SET @sql = 'WITH CTE AS (SELECT [UID] = ''U00001'' ,[NAME] = ''' + @Name + ''') SELECT * FROM CTE';
EXECUTE sp_executesql @sql
```
```
UID NAME
------ ---------
U00001 Jacky Lin
```
如上範例所示,在使用 sp_executesql 預存函式執行 @sql 字串前,可以任意組合與拼湊,除可以動態產生SQL指令外,更可以跳過預存程式的編譯檢查,使SQL程式碼有用極大彈性,但相對上也存在風險,除了無法透過編譯器檢查語法錯誤進行Debug,有問題必須要等到執行時才能發現,這種俗稱兜字串的的執行方式,更可能存在 SQL injection 的安全性風險,因此非必要不建議使用。
***
### 2. 讀取XML格式API
- 程式範例如下:
``` SQL
DECLARE @URL varchar(max);
DECLARE @Obj int
DECLARE @Result int
DECLARE @TableXML table( RayinXML XML )
DECLARE @TEMP_TABLE table
(
tMarginAmt FLOAT null,
tCollateralAmt FLOAT null
)
--此為GET API範例
SELECT @URL = 'http://127.0.0.1/Services.api?APIID=GetRepay'
EXEC @Result = sp_OACreate 'MSXML2.XMLHttp', @Obj OUT
EXEC @Result = sp_OAMethod @Obj, 'open', NULL, 'GET', @URL, false
EXEC @Result = sp_OAMethod @Obj, 'setRequestHeader', NULL, 'Content-Type', 'application/x-www-form-urlencoded'
EXEC @Result = sp_OAMethod @Obj, send, NULL, ''
INSERT @TableXML ( RayinXML )
EXEC @Result = sp_OAGetProperty @Obj , 'responseXML.xml'
INSERT INTO @TEMP_TABLE
SELECT C.value('@MarginAmt', 'FLOAT'),
C.value('@CollateralAmt', 'FLOAT')
FROM @TableXML cross apply
RayinXML.nodes( 'Result/Data/Row ' ) as X(C)
```
***
### 3. 不使用Join語法進行Join
- 假設A表(Staff)如下:
```
UID NAME TeamID
------- --------- ---------
U00001 Jacky Lin A
U00002 Anna Wu B
```
- 假設B表(Team)如下:
```
TeamID Work
------- ---------
A 文書
B 開發
```
- 假設情境:查詢每位員工的工作項目
``` SQL
SELECT [UID] ,[NAME] ,[Work]
FROM Staff ,Team
WHERE Staff.[TeamID] = Team.[TeamID]
```
執行以上指令就會獲得以下結果,其效果相當於INNER JOIN,但為利於其他開發人員閱讀,仍建議使用傳統JOIN寫法。
```
UID NAME Work
------- --------- ---------
U00001 Jacky Lin 文書
U00002 Anna Wu 開發
```
***
## 二、參考資料
- 使用 sp_executesql 要注意的是?
https://dotblogs.com.tw/rainmaker/2015/10/01/153472