首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫

SQL Server 游標存儲過程封裝:動態批量執行 SQL 腳本

     編輯:MySQL 資料庫相關知識

痛點與方案

需動態構建並批量執行多條 SQL 語句(如批量 UPDATE),單條 EXEC 無法事務控制。封裝游標存儲過程 Pr_ExecSQL2 實現:事務包裹 + 游標遍歷 + 錯誤回滾。

存儲過程定義

CREATE PROCEDURE Pr_ExecSQL2
    @Asqlstring VARCHAR(8000)  -- 輸入:返回單列 SQL 語句的查詢
AS
BEGIN
    EXEC ('
        BEGIN TRAN
        DECLARE @ASql VARCHAR(8000)
        DECLARE tnames_cursor CURSOR LOCAL FAST_FORWARD FOR ' + @Asqlstring + '
        OPEN tnames_cursor
        FETCH NEXT FROM tnames_cursor INTO @ASql
        WHILE (@@FETCH_STATUS = 0)
        BEGIN
            PRINT @ASql
            EXEC (@ASql)
            IF @@ERROR <> 0 GOTO FINALEX99v
            FETCH NEXT FROM tnames_cursor INTO @ASql
        END
        CLOSE tnames_cursor
        DEALLOCATE tnames_cursor
        COMMIT TRAN
        RETURN

        FINALEX99v:
        ROLLBACK TRAN
        CLOSE tnames_cursor
        DEALLOCATE tnames_cursor
    ')
END

使用示例

-- 批量更新:從表 b 讀取值更新表 a
DECLARE @sql VARCHAR(8000)
SET @sql = 'SELECT ''UPDATE a SET a.col = '' + QUOTENAME(b.col, '''''') + '' FROM b'''
EXEC Pr_ExecSQL2 @sql

關鍵設計解析

  • LOCAL FAST_FORWARD:只讀、只進游標,性能最優
  • EXEC (@Asqlstring):動態執行傳入的查詢,結果集作為游標源
  • PRINT @ASql:輸出執行的 SQL,便於調試審計
  • @@ERROR + GOTO:錯誤即時跳轉回滾,保證原子性
  • 外層 EXEC ('...'):繞過「存儲過程中不能聲明游標」限制

安全警示與改進

⚠️ SQL 注入高風險! 輸入字符串直接拼接執行。生產環境必須:
  • 嚴格驗證 @Asqlstring 來源(僅允許內部構建)
  • 改用 sp_executesql + 參數化
  • 限制執行權限(僅 DML,禁止 DDL)

現代替代方案 (SQL Server 2008+)

-- 使用 Table-Valued Parameter + MERGE 或批量 INSERT/UPDATE
-- 或啟用 CLR 集成編寫安全的批量執行組件
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved