Chuyển đổi sang nvarchar(max)
và quay lại để ntext
làm cho cuộc sống đơn giản hơn từ quan điểm mã, nhưng điều đó có nghĩa là chuyển đổi và viết lại toàn bộ giá trị (có lẽ rất lớn), với tất cả chi phí CPU và ghi nhật ký.
Một cách khác là sử dụng UPDATETEXT
. Điều này không được chấp nhận, giống như ntext
, nhưng nó có thể làm giảm đáng kể chi phí đăng nhập. Mặt khác, nó có nghĩa là sử dụng các con trỏ văn bản và nó chỉ hoạt động trên một hàng tại một thời điểm.
Mã ví dụ sau sử dụng một con trỏ để khắc phục giới hạn đó và sử dụng PATINDEX
thay vì vì CHARINDEX
trước đây là một trong số ít các hàm hoạt động trực tiếp với ntext
:
Dữ liệu mẫu
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.')
);
Khai báo con trỏ
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;
Vòng lặp xử lý
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;