Mengubah nvarchar(max)
dan kembali ke ntext
memang membuat hidup lebih sederhana dari sudut pandang kode, tetapi itu berarti mengubah dan menulis ulang nilai keseluruhan (mungkin sangat besar), dengan semua CPU dan logging overhead yang menyiratkan.
Alternatifnya adalah menggunakan UPDATETEXT
. Ini sudah usang, sama seperti ntext
, tetapi dapat mengurangi overhead logging secara signifikan. Pada sisi negatifnya, itu berarti menggunakan petunjuk teks, dan itu hanya beroperasi pada satu baris pada satu waktu.
Kode contoh berikut menggunakan kursor untuk mengatasi keterbatasan itu, dan menggunakan PATINDEX
alih-alih CHARINDEX
karena yang pertama adalah salah satu dari beberapa fungsi yang bekerja secara langsung dengan ntext
:
Contoh data
CREATE TABLE dbo.PhilsTable
(
comment ntext NULL,
anothercomment nvarchar(50) NULL
);
INSERT dbo.PhilsTable
(comment, anothercomment)
VALUES
(
CONVERT(ntext,
N'This is a test UPDATEHERE This is the end of the test ' +
REPLICATE (CONVERT(nvarchar(max), N'x'), 1000000)),
CONVERT(nvarchar(50), N'. This is inserted.')
),
(
CONVERT(ntext,
N'This is a test UPDATEHERE This is the end of the test ' +
REPLICATE (CONVERT(nvarchar(max), N'x'), 1000000)),
CONVERT(nvarchar(50), N'. This is inserted.')
),
(
CONVERT(ntext,
N'This is a test UPDATEHERE This is the end of the test ' +
REPLICATE (CONVERT(nvarchar(max), N'x'), 1000000)),
CONVERT(nvarchar(50), N'. This is inserted.')
);
Deklarasi kursor
DECLARE c
CURSOR GLOBAL
FORWARD_ONLY
DYNAMIC
SCROLL_LOCKS
TYPE_WARNING
FOR
SELECT
TxtPtr = TEXTPTR(PT.comment),
Src = PT.anothercomment,
Offset = PATINDEX(N'%UPDATEHERE%', PT.comment) + LEN(N'UPDATEHERE') - 1
FROM dbo.PhilsTable AS PT
WHERE
PT.comment LIKE N'%UPDATEHERE%'; -- LIKE works with ntext
OPEN c;
Memproses loop
DECLARE
@Ptr binary(16),
@Src nvarchar(50),
@Offset integer;
SET STATISTICS XML OFF; -- No cursor fetch plans
BEGIN TRANSACTION;
WHILE 1 = 1
BEGIN
FETCH c INTO @Ptr, @Src, @Offset;
IF @@FETCH_STATUS = -2 CONTINUE; -- row missing
IF @@FETCH_STATUS = -1 BREAK; -- no more rows
IF 1 = TEXTVALID('dbo.PhilsTable.comment', @Ptr)
BEGIN
-- Modify ntext value
UPDATETEXT dbo.PhilsTable.comment @Ptr @Offset 0 @Src;
END;
END;
COMMIT TRANSACTION;
CLOSE c; DEALLOCATE c;