SQL Server 2008 中的動態 SQL 與表格變數:解決方案
SQL Server 2008 在動態 SQL 中使用表格變數時面臨挑戰。本文解決了這個問題並提供了實用的解決方法。
問題:未宣告的表變數
常見場景涉及預存程序嘗試執行引用本地聲明的表變數的動態 SQL 查詢。 結果通常是一個錯誤,表示這些變數在動態 SQL 上下文中未聲明。 考慮這個例子:
<code class="language-sql">DECLARE @col_name NVARCHAR(MAX), @sqlstat NVARCHAR(MAX), @curr_row INT, @curr_row1 INT; -- ... other code to populate @curr_row and @curr_row1 ... DECLARE @RelPro TABLE (RowID INT, Assoc_Item_1 INT, Assoc_Item_2 INT, ...); DECLARE @TSku TABLE (tid INT, relsku INT); -- ... populate @RelPro and @TSku ... SET @col_name = 'Assoc_Item_' + CONVERT(NVARCHAR(2), @curr_row1); SET @sqlstat = 'UPDATE @RelPro SET ' + @col_name + ' = (SELECT relsku FROM @TSku WHERE tid = ' + CONVERT(NVARCHAR(2), @curr_row1) + ') WHERE RowID = ' + CONVERT(NVARCHAR(2), @curr_row); EXEC sp_executesql @sqlstat;</code>
此程式碼將失敗並出現錯誤:
<code>Must declare the table variable "@RelPro". Must declare the table variable "@TSku".</code>
解:表值參數
SQL Server 2008 及更高版本提供了一個強大的解決方案:表值參數。雖然這些參數會阻止在動態 SQL 中直接修改表數據,但它們允許引用表的內容。為了適應上面的程式碼,我們將建立一個使用者定義的表格類型,然後將其用作參數:
<code class="language-sql">-- Create a user-defined table type CREATE TYPE MySkuTable AS TABLE (tid INT, relsku INT); GO -- Stored Procedure using Table-Valued Parameter CREATE PROCEDURE UpdateRelPro (@TSku MySkuTable READONLY, @curr_row INT, @curr_row1 INT) AS BEGIN DECLARE @col_name NVARCHAR(MAX), @sqlstat NVARCHAR(MAX); SET @col_name = 'Assoc_Item_' + CONVERT(NVARCHAR(2), @curr_row1); SET @sqlstat = N'UPDATE @RelPro SET ' + @col_name + N' = (SELECT relsku FROM @TSku WHERE tid = ' + CONVERT(NVARCHAR(2), @curr_row1) + N') WHERE RowID = ' + CONVERT(NVARCHAR(2), @curr_row); -- Declare @RelPro within the procedure DECLARE @RelPro TABLE (RowID INT, Assoc_Item_1 INT, Assoc_Item_2 INT, ...); -- ... populate @RelPro ... EXEC sp_executesql @sqlstat, N'@RelPro MyTable READONLY', @RelPro = @RelPro; END; GO -- Example Usage: DECLARE @TSku MySkuTable; INSERT INTO @TSku VALUES (1, 10), (2, 20); DECLARE @RelPro TABLE (RowID INT, Assoc_Item_1 INT, Assoc_Item_2 INT); INSERT INTO @RelPro VALUES (1, NULL, NULL); EXEC UpdateRelPro @TSku, 1, 1;</code>
,將表值參數 sp_executesql
和表變數 @TSku
(在過程內宣告)作為參數傳遞。 @RelPro
關鍵字可防止修改輸入表。 請記住在儲存過程中聲明READONLY
@RelPro
內部。 該技術允許在動態 SQL 中安全有效地使用表變數。
以上是SQL Server 2008中如何在動態SQL語句中正確使用表格變數?的詳細內容。更多資訊請關注PHP中文網其他相關文章!