SQL सर्वर - NTEXT कॉलम और स्ट्रिंग हेरफेर


11

मेरे पास एक NTEXTकॉलम है जिसमें एक कॉलम है comments। मेरे पास एक दूसरा स्ट्रिंग है, आइए इसे anothercomment(ए varchar) कहते हैं commentsजिसे शब्द के बाद दिए गए स्ट्रिंग के अंदर रखने की आवश्यकता होती है UPDATEHERE

स्ट्रिंग को nvarchar(max)छोटा करने के लिए कास्टिंग करना comments, इसलिए मैं पसंद का उपयोग नहीं कर सकता CHARINDEX()( Msg 8152, Level 16, State 10, Line 2 String or binary data would be truncated.)मैंने यह datalength()जांचने के लिए उपयोग किया है कि कुछ हजार कॉलम हैं> 8000 वर्ण।

एक उदाहरण जो मैं प्राप्त करना चाहता हूं (बहुत लंबे तार के साथ)

टिप्पणियाँ - This is a test UPDATEHERE This is the end of the test

एक और समझौता - . This is inserted.

परिणामी स्ट्रिंग - This is a test UPDATEHERE. This is inserted. This is the end of the test

मुझे लगता है कि यह एक सामान्य varchar()/ के साथ तुच्छ है nvarchar(), लेकिन ntextसाथ काम करने के लिए एक पूर्ण और पूरी तरह से बुरा सपना है। मुझे लगता है कि यह एक पदावनत डेटा प्रकार है, लेकिन मैंने प्रश्न में आवेदन नहीं लिखा था।

जवाबों:


8

में कनवर्ट कर रहा nvarchar(max)है जब तक आप के साथ कुछ गलत कर रहे हैं काम करना चाहिए अपनेCHARINDEX()

इस कोड स्निपेट को आज़माएं, इसे वही चाहिए जो आपको चाहिए।

-- Create the table
CREATE TABLE [dbo].[PhilsTable](
    [comment] [ntext] NULL,
    [anothercomment] [nvarchar](50) NULL
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY];

GO

-- insert very long string
INSERT INTO [dbo].[PhilsTable] (comment, anothercomment) VALUES (N'This is a test UPDATEHERE This is the end of the test' + REPLICATE (CAST(N'x' AS nvarchar(max)), 1000000), 'this goes in here');

-- verify data
SELECT DATALENGTH(comment), *  FROM [dbo].[PhilsTable];

-- perform replace
SELECT CAST(REPLACE(CAST(comment AS NVARCHAR(MAX)),'UPDATEHERE','UPDATEHERE' + anothercomment) AS NTEXT) FROM [dbo].[PhilsTable];

DROP TABLE [dbo].[PhilsTable];

धन्यवाद बयान के साथ मदद करने के लिए एंड्री एम के लिए धन्यवाद REPLICATE


10

एक कोड बिंदु से जीवन को सरल बनाने nvarchar(max)और वापस करने के लिए परिवर्तित करना ntext, लेकिन इसका अर्थ है सभी सीपीयू और लॉगिंग ओवरहेड के साथ पूरे (शायद बहुत बड़े) मान को परिवर्तित करना और फिर से लिखना, जिसका अर्थ है।

एक विकल्प का उपयोग करना है 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;
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.