首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 數據庫知識 >  >> SQL Server 資料庫 >> 關於SqlServer

MSSQL text/ntext 欄位惡意腳本清除實戰:使用 PATINDEX 與 UPDATETEXT

     編輯:關於SqlServer

問題背景

text/ntext 型別不支援 REPLACE() 函數,若資料庫遭大量注入惡意腳本(如 <script src="..."></script>),需逐列掃描替換。本文提供完整游標方案。

核心邏輯

  1. 宣告搜尋字串 @s_str 與替換字串 @d_str(通常為空字串)。
  2. 搜尋字串加上萬用字元:SET @s_str = '%' + @s_str + '%'。
  3. 建立游標選出受影響資料列主鍵(P_ID)。
  4. 逐列處理:取得文字指標 textptr()、資料長度 datalength()、首次出現位置 patindex()。
  5. 迴圈呼叫 UPDATETEXT 逐段覆寫,直到 patindex() 回傳 0。
  6. 關閉游標釋放資源。

完整範例程式碼

DECLARE @s_str NVARCHAR(4000), @d_str NVARCHAR(4000);
SELECT @s_str = '<script src="https://my.stsw518.cn/a002/1.js" src="https://my.stsw518.cn/a002/1.JS"></script>',
       @d_str = '';

SET @s_str = '%' + @s_str + '%';

DECLARE @id BIGINT;
DECLARE cur CURSOR FOR
    SELECT P_ID FROM Product
    WHERE P_Intro LIKE @s_str;

OPEN cur;
FETCH NEXT FROM cur INTO @id;

WHILE @@FETCH_STATUS = 0
BEGIN
    DECLARE @p VARBINARY(16), @p1 INT, @p2 INT, @rplen INT, @step INT, @len INT;
    
    SELECT @p = TEXTPTR(P_Intro),
           @rplen = LEN(@s_str) - 2,
           @step = LEN(@d_str),
           @p1 = PATINDEX(@s_str, P_Intro),
           @len = DATALENGTH(P_Intro),
           @p2 = 0
    FROM Product WHERE P_ID = @id;

    WHILE @p1 > 0
    BEGIN
        SET @p2 = @p1 + @p2 - 1;
        UPDATETEXT Product.P_Intro @p @p2 @rplen @d_str;
        SELECT @p2 = @p2 + 1,
               @p1 = PATINDEX(@s_str, SUBSTRING(P_Intro, @p2 + 1, @len))
        FROM Product WHERE P_ID = @id;
    END

    FETCH NEXT FROM cur INTO @id;
END

CLOSE cur;
DEALLOCATE cur;

關鍵點提醒

  • PATINDEX 僅支援 text/ntext/varchar 等型別,textptr() 必須在同一交易內使用。
  • UPDATETEXT 參數:@p 文字指標、@p2 起始位移(0-based)、@rplen 刪除長度、@d_str 插入字串。
  • 大量資料時游標效能較差,可考慮分批次處理或升級至 varchar(max) 使用 REPLACE()。
  • 修改前務必完整備份,建議先在測試環境驗證。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved