## 一、特殊指令與函式 ### 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