การแปลงไปnvarchar(max)
และกลับเพื่อntext
ทำให้ชีวิตง่ายขึ้นจากมุมมองโค้ด แต่มันหมายถึงการแปลงและเขียนค่าทั้งหมด (อาจมีขนาดใหญ่มาก) ด้วย CPU และการบันทึกค่าใช้จ่ายทั้งหมดที่มีความหมาย
UPDATETEXT
ทางเลือกคือการใช้งาน สิ่งนี้เลิกใช้แล้วntext
แต่สามารถลดค่าใช้จ่ายในการบันทึกได้อย่างมาก ในข้อเสียหมายถึงการใช้พอยน์เตอร์พอยน์เตอร์และทำงานได้ทีละแถวเท่านั้น
โค้ดตัวอย่างต่อไปนี้ใช้เคอร์เซอร์เพื่อหลีกเลี่ยงข้อ จำกัด นั้นและใช้PATINDEX
แทนCHARINDEX
เนื่องจากในอดีตเป็นหนึ่งในไม่กี่ฟังก์ชันที่ทำงานโดยตรงกับntext
:
ข้อมูลตัวอย่าง
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.')
);
ประกาศเคอร์เซอร์
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;
กำลังประมวลผลลูป
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;