text/ntext 型別不支援 REPLACE() 函數,若資料庫遭大量注入惡意腳本(如 <script src="..."></script>),需逐列掃描替換。本文提供完整游標方案。
@s_str 與替換字串 @d_str(通常為空字串)。SET @s_str = '%' + @s_str + '%'。P_ID)。textptr()、資料長度 datalength()、首次出現位置 patindex()。UPDATETEXT 逐段覆寫,直到 patindex() 回傳 0。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()。