--select * from dbo.cms_detail
if exists(select 1 from tempdb.dbo.sysobjects where name like '#cms_detailtmp%')
DROP TABLE #cms_detailtmp
CREATE TABLE #cms_detailtmp
(
ID INT IDENTITY(1,1) PRIMARY KEY,
A TEXT
)
set nocount on
DECLARE @sTableName SYSNAME
DECLARE @sFieLd SYSNAME
DECLARE @sSrc VARCHAR(20)
DECLARE @sDest VARCHAR(20)
SET @sTableName = 'cms_detail' -- 待更新的表的名稱
SET @sField = 'content' -- 待更新的字段的名稱
SET @sSrc = '.MEGAJOY.COM' -- 要被替換的字符串(源字符串)
SET @sDest = '.JOY.CN' -- 進行替換的目標字符串
DECLARE @PTRVAL BINARY(16) -- 指向當前文本字段的指針
DECLARE @VAL VARCHAR(8000) -- 當前讀取的文本字段的部分
DECLARE @PREVVAL VARCHAR(8000) -- 由於源字符串跨界產生的源字符串前綴回退部分
DECLARE @VALLEN INT -- 當前讀取的文本字段的長度
DECLARE @STATEMENT NVARCHAR(512) -- 進行執行sp_executesql的SQL語句部分
DECLARE @ISNTEXT BIT -- 是否NTEXT字段類型0: TEXT 1: NTEXT
DECLARE @READPTR INT -- 當前TEXT或者NTEXT字段已經讀取或者處理的字符偏移量
DECLARE @READLEN INT -- 當次TEXT或者NTEXT字段讀取的長度
DECLARE @SRCLEN INT -- 源字符串的長度
DECLARE @DESTLEN INT -- 目標字符串的長度
DECLARE @VALBINARY VARBINARY(8000) -- 本次讀取的文本字段的BINARY表示,用來識別是否已經截斷了一個DBCS字符
DECLARE @VALBINARYLEN INT -- 本次讀取的文本字段的BINARY表示的長度
DECLARE @HALFDBCS INT -- 當前識別的是否DBCS的一部分
SET @SRCLEN = LEN( @sSrc )
SET @DESTLEN = LEN( @sDest )
DECLARE csrTextUpdate CURSOR LOCAL FOR
SELECT TEXTPTR(content),
DATALENGTH(content)
FROM cms_detail
FOR UPDATE OF content
OPEN csrTextUpdate
declare @count int
select @count=count(*) from cms_detail
print '共'+cast(@count as varchar);
set @count =1;
-- xtype = 35 爲TEXT xtype = 99 爲NTEXT
IF EXISTS( SELECT * FROM SYSCOLUMNS WHERE ID = OBJECT_ID('cms_detail') AND NAME = @sField AND XTYPE = 35 )
SET @ISNTEXT = 0
ELSE
SET @ISNTEXT = 1
FETCH csrTextUpdate INTO @PTRVAL, @VALLEN
WHILE @@FETCH_STATUS = 0
BEGIN
print '現在是第'+cast(@count as varchar);
set @count=@count+1;
IF @VALLEN > 8000
BEGIN
SET @VALLEN = CASE WHEN @ISNTEXT = 1 THEN @VALLEN / 2 ELSE @VALLEN END
SET @READPTR = 0
SET @READLEN = CASE WHEN @VALLEN > @READPTR + 2000 THEN 2000 ELSE @VALLEN - @READPTR END
TRUNCATE TABLE #cms_detailtmp
-- 分拆TEXT字段到#cms_detailtmp表
WHILE @READPTR < @VALLEN
BEGIN
SET @READLEN = CASE WHEN @VALLEN > @READPTR + 2000 THEN 2000 ELSE @VALLEN - @READPTR END
SET @STATEMENT = N'READTEXT cms_detail.content @PTRVAL '
+ CONVERT( NVARCHAR, @READPTR ) + ' '
+ CONVERT( NVARCHAR, @READLEN )
SET @READPTR = @READPTR + @READLEN
INSERT INTO #cms_detailtmp
EXEC sp_executesql @STATEMENT,
N'@PTRVAL BINARY(16)',
@PTRVAL
-- 判斷最後一個字符是否爲中文字符,如果是,則需要進行回退操作
IF @@ROWCOUNT = 1 AND @ISNTEXT = 0
BEGIN
SELECT @VALBINARY = CONVERT( VARBINARY(8000), CONVERT( VARCHAR(8000), A ))
FROM #cms_detailtmp WHERE ID = @@IDENTITY
SET @VALBINARYLEN = DATALENGTH(@VALBINARY)
IF @VALBINARYLEN = @READLEN
BEGIN
SET @HALFDBCS = 0
END
ELSE
BEGIN
SET @HALFDBCS = 1
END
IF @HALFDBCS = 1
BEGIN
-- 回退一個字符串
UPDATE #cms_detailtmp
SET A = CONVERT( VARCHAR(8000), SUBSTRING( @VALBINARY, 1, @READLEN - 1 ) )
WHERE ID = @@IDENTITY
SET @READPTR = @READPTR - 1
END
END
END
-- 進行分批替換,如果有需要被替換的字符串跨段的情況需要進行跨段處理
DECLARE csrTmp CURSOR LOCAL FOR
SELECT A FROM #cms_detailtmp
FOR UPDATE OF A
OPEN csrTmp
FETCH csrTmp INTO @VAL
SET @PREVVAL = ''
WHILE @@FETCH_STATUS = 0
BEGIN
SET @VAL = REPLACE( @PREVVAL + @VAL, @sSrc, @sDest )
SET @VALLEN = LEN(@VAL)
SET @READPTR = CASE WHEN @SRCLEN > @VALLEN THEN @VALLEN ELSE @SRCLEN END
SET @PREVVAL = ''
WHILE @READPTR > 0
BEGIN
IF RIGHT( @VAL, @READPTR ) = LEFT( @sSrc, @READPTR )
BEGIN
-- 找到前綴,將當前的@VAL截斷一部分
UPDATE #cms_detailtmp
SET [A] = LEFT( @VAL, @VALLEN - @READPTR )
WHERE CURRENT OF csrTmp
SET @PREVVAL = RIGHT( @VAL, @READPTR )
BREAK
END
SET @READPTR = @READPTR - 1
END
IF @PREVVAL = ''
BEGIN
UPDATE #cms_detailtmp
SET [A] = @VAL
WHERE CURRENT OF csrTmp
END
FETCH csrTmp INTO @VAL
END
DEALLOCATE csrTmp
-- 更新TEXT字段
UPDATETEXT cms_detail.content @PTRVAL 0 NULL ''
DECLARE csrUpdateText CURSOR LOCAL FOR
SELECT A FROM #cms_detailtmp
OPEN csrUpdateText
FETCH csrUpdateText INTO @VAL
WHILE @@FETCH_STATUS = 0
BEGIN
UPDATETEXT cms_detail.content @PTRVAL NULL 0 @VAL
FETCH csrUpdateText INTO @VAL
END
DEALLOCATE csrUpdateText
END
ELSE
BEGIN
-- 如果是NTEXT的類型,字符串的長度爲字節長度的/2
UPDATE cms_detail
SET content = REPLACE( CONVERT( VARCHAR(8000), content), @sSrc, @sDest )
WHERE CURRENT OF csrTextUpdate
END
FETCH csrTextUpdate INTO @PTRVAL, @VALLEN
END
DEALLOCATE csrTextUpdate
GO
數據庫ntext,text字段的內容批量替換儲存過程 轉
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.