व्हाट्सएप ट्रिम करें (रिक्त स्थान, टैब, न्यूलाइन्स)


10

मैं SQL सर्वर 2014 पर हूं और मुझे एक कॉलम की सामग्री के प्रारंभ और अंत से व्हाट्सएप को साफ करने की आवश्यकता है, जहां व्हाट्सएप सरल स्थान, टैब या नईलाइन (दोनों \nऔर \r\n) हो सकता है; जैसे

'    this content    '                          should become 'this content'
'  \r\n   \t\t\t this \r\n content \t  \r\n   ' should become 'this \r\n content'

और इसी तरह।

मैं केवल पहला मामला ही हासिल कर पाया था

UPDATE table t SET t.column = LTRIM(RTRIM(t.column))

लेकिन अन्य मामलों के लिए यह काम नहीं करता है।

जवाबों:


8

SQL Server 2017 या नए का उपयोग करने वाले किसी के लिए

आप TRIM बिल्ट-इन फ़ंक्शन का उपयोग कर सकते हैं । उदाहरण के लिए:

DECLARE @Test NVARCHAR(4000);
SET @Test = N'  
    ' + NCHAR(0x09) + N'  ' + NCHAR(0x09) + N' this 
 ' + NCHAR(0x09) + NCHAR(0x09) + N'  content' + NCHAR(0x09) + NCHAR(0x09) + N'  
' + NCHAR(0x09) + N' ' + NCHAR(0x09) + NCHAR(0x09) + N'     ';

SELECT N'~'
        + TRIM(NCHAR(0x09) + NCHAR(0x20) + NCHAR(0x0D) + NCHAR(0x0A) FROM @Test)
        + N'~';

कृपया ध्यान दें कि डिफ़ॉल्ट व्यवहार TRIMकेवल रिक्त स्थान को हटाने के लिए है, इसलिए टैब और newlines (CR + LFs) को निकालने के लिए, आपको characters FROMक्लॉज़ निर्दिष्ट करने की आवश्यकता है ।

इसके अलावा, मैंने चर NCHAR(0x09)वर्णों में टैब वर्णों के लिए उपयोग किया @Testताकि उदाहरण कोड को कॉपी-और-पेस्ट किया जा सके और सही वर्णों को बनाए रखा जा सके। अन्यथा, जब यह पृष्ठ प्रदान किया जाता है तो टैब रिक्त स्थान में परिवर्तित हो जाते हैं।

SQL सर्वर 2016 या पुराने का उपयोग करने वाले किसी के लिए

आप एक फ़ंक्शन बना सकते हैं, या तो SQLCLR स्केलर UDF या T-SQL इनलाइन TVF (iTVF) के रूप में। T-SQL इनलाइन TVF निम्नानुसार होगा:

CREATE
--ALTER
FUNCTION dbo.TrimChars(@OriginalString NVARCHAR(4000), @CharsToTrim NVARCHAR(50))
RETURNS TABLE
WITH SCHEMABINDING
AS RETURN
WITH cte AS
(
  SELECT PATINDEX(N'%[^' + @CharsToTrim + N']%', @OriginalString) AS [FirstChar],
         PATINDEX(N'%[^' + @CharsToTrim + N']%', REVERSE(@OriginalString)) AS [LastChar],
        LEN(@OriginalString + N'~') - 1 AS [ActualLength]
)
SELECT cte.[ActualLength],
       [FirstChar],
       ((cte.[ActualLength] - [LastChar]) + 1) AS [LastChar],
       SUBSTRING(@OriginalString, [FirstChar],
                 ((cte.[ActualLength] - [LastChar]) - [FirstChar] + 2)) AS [FixedString]
FROM   cte;
GO

और इसे निम्न प्रकार से चलाना:

DECLARE @Test NVARCHAR(4000);
SET @Test = N'  
    ' + NCHAR(0x09) + N'  ' + NCHAR(0x09) + N' this 
 ' + NCHAR(0x09) + NCHAR(0x09) + N'  content' + NCHAR(0x09) + NCHAR(0x09) + N'  
' + NCHAR(0x09) + N' ' + NCHAR(0x09) + NCHAR(0x09) + N'     ';

SELECT N'~' + tc.[FixedString] + N'~' AS [proof]
FROM   dbo.TrimChars(@Test, NCHAR(0x09) + NCHAR(0x20) + NCHAR(0x0D) + NCHAR(0x0A)) tc;

यह दिखाता है:

proof
----
~this 
              content~

और तुम एक में उपयोग कर सकते हैं कि UPDATEका उपयोग करते हुए CROSS APPLY:

UPDATE tbl
SET    tbl.[Column] = itvf.[FixedString]
FROM   SchemaName.TableName tbl
CROSS APPLY  dbo.TrimChars(tbl.[Column],
                           NCHAR(0x09) + NCHAR(0x20) + NCHAR(0x0D) + NCHAR(0x0A)) itvf

जैसा कि शुरुआत में उल्लेख किया गया है, यह वास्तव में SQLCLR के माध्यम से भी आसान है क्योंकि .NET में एक Trim()विधि शामिल है जो ठीक उसी प्रकार से होती है जो आप चाहते हैं। आप या तो कॉल करने के लिए अपना खुद का कोड कर सकते हैं SqlString.Value.Trim(), या आप बस SQL # लाइब्रेरी के नि: शुल्क संस्करण को स्थापित कर सकते हैं (जो मैंने बनाया था, लेकिन यह फ़ंक्शन नि: शुल्क संस्करण में है) और या तो String_Trim का उपयोग करें (जो कि केवल सफेद स्थान करता है) या String_TrimCs कहाँ आप पात्रों को दोनों तरफ से ट्रिम करने के लिए पास करते हैं (ठीक ऊपर दिखाए गए iTVF की तरह)।

DECLARE @Test NVARCHAR(4000);
SET @Test = N'  
    ' + NCHAR(0x09) + N'  ' + NCHAR(0x09) + N' this 
 ' + NCHAR(0x09) + NCHAR(0x09) + N'  content' + NCHAR(0x09) + NCHAR(0x09) + N'  
' + NCHAR(0x09) + N' ' + NCHAR(0x09) + NCHAR(0x09) + N'     ';

SELECT N'~' + SQL#.String_Trim(@Test) + N'~' AS [proof];

और यह ठीक उसी स्ट्रिंग को वापस करता है जैसा कि iTVF उदाहरण आउटपुट में ऊपर दिखाया गया है। लेकिन एक स्केल UDF होने के नाते, आप इसे निम्नानुसार उपयोग करेंगे UPDATE:

UPDATE tbl
SET    tbl.[Column] = SQL#.String_Trim(itvf.[Column])
FROM   SchemaName.TableName tbl

लाखों पंक्तियों का उपयोग करने के लिए उपरोक्त में से कोई एक कुशल होना चाहिए। इनलाइन TVFs मल्टी स्टेटमेंट TVFs और T-SQL स्केलर UDFs के विपरीत हैं। और, SQLCLR स्केलर UDFs को समानांतर योजनाओं में उपयोग किए जाने की क्षमता है, जब तक वे चिह्नित हैं IsDeterministic=trueऔर या तो डेटाअटे टाइप नहीं करते हैं Read(उपयोगकर्ता और सिस्टम डेटा एक्सेस दोनों के लिए डिफ़ॉल्ट है None), और दोनों ही स्थितियां हैं ऊपर उल्लिखित दोनों SQLCLR फ़ंक्शन के लिए सही है।


4

आप अपने डेटा के प्रारंभ और अंत से अपमानजनक पात्रों को हटाने के लिए टीवीएफ (टेबल-वैल्यू-फंक्शन) का उपयोग करने पर विचार कर सकते हैं।

परीक्षण डेटा रखने के लिए एक तालिका बनाएँ:

IF COALESCE(OBJECT_ID('dbo.TrimTest'), 0) <> 0
BEGIN
    DROP TABLE dbo.TrimTest;
END
CREATE TABLE dbo.TrimTest
(
    SampleData VARCHAR(50) NOT NULL
);

INSERT INTO dbo.TrimTest (SampleData)
SELECT CHAR(13) + CHAR(10) + CHAR(9) + 'this is ' + CHAR(13) + CHAR(10) + ' a test' + CHAR(13) + CHAR(10);
GO

TVF बनाएँ:

IF COALESCE(OBJECT_ID('dbo.StripCrLfTab'), 0) <> 0
BEGIN
    DROP FUNCTION dbo.StripCrLfTab;
END
GO
CREATE FUNCTION dbo.StripCrLfTab
(
    @val NVARCHAR(1000)
)
RETURNS @Results TABLE
(
    TrimmedVal NVARCHAR(1000) NULL
)
AS
BEGIN
    DECLARE @TrimmedVal NVARCHAR(1000);
    SET @TrimmedVal = CASE WHEN RIGHT(@val, 1) = CHAR(13) OR RIGHT(@val, 1) = CHAR(10) OR RIGHT(@val, 1) = CHAR(9)
            THEN LEFT(
                CASE WHEN LEFT(@val, 1) = CHAR(13) OR LEFT(@val, 1) = CHAR(10) OR LEFT(@val, 1) = CHAR(9)
                THEN RIGHT(@val, LEN(@val) - 1)
                ELSE @val
                END
                , LEN(@val) -1 )
            ELSE
                CASE WHEN LEFT(@val, 1) = CHAR(13) OR LEFT(@val, 1) = CHAR(10) OR LEFT(@val, 1) = CHAR(9)
                THEN RIGHT(@val, LEN(@val) - 1)
                ELSE @val
                END
            END;
    IF @TrimmedVal LIKE (CHAR(13) + '%')
        OR @TrimmedVal LIKE (CHAR(10) + '%')
        OR @TrimmedVal LIKE (CHAR(9) + '%')
        OR @TrimmedVal LIKE ('%' + CHAR(13))
        OR @TrimmedVal LIKE ('%' + CHAR(10))
        OR @TrimmedVal LIKE ('%' + CHAR(9))
        SELECT @TrimmedVal = tv.TrimmedVal
        FROM dbo.StripCrLfTab(@TrimmedVal) tv;
    INSERT INTO @Results (TrimmedVal)
    VALUES (@TrimmedVal);
    RETURN;
END;
GO

परिणाम दिखाने के लिए TVF चलाएँ:

SELECT tt.SampleData
    , stt.TrimmedVal
FROM dbo.TrimTest tt
CROSS APPLY dbo.StripCrLfTab(tt.SampleData) stt;

परिणाम:

यहाँ छवि विवरण दर्ज करें

टीवीएफ खुद को पुनरावर्ती कहता है जब तक कि समारोह में शुरू किए गए स्ट्रिंग के अंत और अंत में कोई शेष आक्रामक चरित्र नहीं होते हैं। यह बड़ी संख्या में पंक्तियों में अच्छा प्रदर्शन करने की संभावना नहीं है, लेकिन संभवतः ठीक काम करेगा यदि आप डेटा को ठीक करने के लिए इसका उपयोग कर रहे हैं क्योंकि यह डेटाबेस में डाला गया है।

आप इसे अपडेट स्टेटमेंट में इस्तेमाल कर सकते हैं:

UPDATE dbo.TrimTest
SET TrimTest.SampleData = stt.TrimmedVal
FROM dbo.TrimTest tt
CROSS APPLY dbo.StripCrLfTab(tt.SampleData) stt;


SELECT *
FROM dbo.TrimTest;

परिणाम (पाठ के रूप में):

यहाँ छवि विवरण दर्ज करें


धन्यवाद मैक्स, दुर्भाग्य से मुझे कई तालिकाओं में बड़ी संख्या में पंक्तियों (लाखों) को साफ करना है, मुझे उम्मीद है कि किसी फ़ंक्शन में उपयोग किया जा सकता है UPDATEजैसे LTRIM/ RTRIM, UPDATE table t SET t.column = TRIM(t.column, CONCAT(CHAR(9), CHAR(10), CHAR(13)))किसी TRIM( expression, charlist )फ़ंक्शन की पंक्तियों की सूची को स्वीकार करने वाले फ़ंक्शन की पंक्तियों में कुछ को ट्रिम करने के लिए कई स्क्रिप्टिंग भाषाओं की तरह।
गियोवन्नी लोवाटो

मैंने इसके बारे में जो चेतावनी दी थी "शायद" बहुत सारी पंक्तियों पर अच्छा काम नहीं कर रहा है या कोई समस्या नहीं हो सकती है। अगर आप ऐसा सिर्फ एक बार कर रहे हैं, तो यह समस्या नहीं हो सकती है। आप इसे एक गैर-उत्पादन वातावरण में परीक्षण करना चाह सकते हैं ताकि आप देख सकें कि इसमें कितना समय लगता है।
मैक्स वर्नोन

मैं अपने उत्तर को यह दिखाने के लिए अपडेट करूंगा कि आप एक updateवक्तव्य में इसका उपयोग कैसे करेंगे ।
मैक्स वर्नोन

1

मुझे सिर्फ इस विशेष स्थिति में समस्या थी, मुझे हर क्षेत्र को सफेद स्थानों के साथ खोजने और साफ करने की आवश्यकता थी, लेकिन मुझे अपने डेटाबेस फ़ील्ड्स में 4 प्रकार की कब्ज़े वाली सफेद जगह मिली (संदर्भ ASCII कोड तालिका):

  • क्षैतिज टैब (चार (9))
  • नई लाइन (चार (10))
  • वर्टिकल टैब (चार (9))
  • अंतरिक्ष (चार (32))

शायद यह क्वेरी आपकी मदद कर सकती है।

UPDATE @TABLE SET @COLUMN = replace(replace(replace(replace(@COLUMN,CHAR(9),''),CHAR(10),''),CHAR(13),''),CHAR(32),'')

यह व्हाट्सएप को खेतों के बीच से भी साफ करता है, न कि केवल शुरुआत और अंत के रूप में।
कॉलिन टी हार्ट

हां, आप सही हैं, मैं संपादित
करूंगा

-1

आपको दूसरा उदाहरण पार्स करना होगा क्योंकि LTRIM / RTRIM केवल रिक्त स्थान को ट्रिम करते हैं। आप वास्तव में उस ट्रिम को ट्रिम करना चाहते हैं जिसे SQL डेटा (/ r, / t, आदि) मानता है। यदि आप उन मूल्यों को जानते हैं जिन्हें आप ढूंढ रहे हैं, तो उन्हें बदलने के लिए केवल REPLACE का उपयोग करें। बेहतर अभी तक, एक फ़ंक्शन लिखें और इसे कॉल करें।


-1

यदि आप चाहें, तो मेरे सुरुचिपूर्ण समारोह का उपयोग करें:

CREATE FUNCTION s_Trim
(
    @s nvarchar(max)
)
RETURNS nvarchar(max)
AS
BEGIN
    -- Create comparators for LIKE operator
    DECLARE @whitespaces nvarchar(50) = CONCAT('[ ', CHAR(9), CHAR(10), CHAR(13), ']'); -- Concat chars that you consider as whitespaces
    DECLARE @leftComparator nvarchar(50) = @whitespaces + '%',
            @rightComparator nvarchar(50) = '%' + @whitespaces;
    -- LTRIM
    WHILE @s LIKE @leftComparator AND LEN(@s + 'x') > 1 SET @s = RIGHT(@s, LEN(@s + 'x') - 2)
    -- RTRIM
    WHILE @s LIKE @rightComparator AND LEN(@s + 'x') > 1 SET @s = LEFT(@s, LEN(@s + 'x') - 2)

    RETURN @s;
END
GO

1
स्केलर मूल्यवान कार्य शायद ही सुरुचिपूर्ण हैं। वे क्वेरी को क्रमिक रूप से चलाने के लिए बाध्य करते हैं, और प्रति पंक्ति एक बार निष्पादित करते हैं (क्वेरी के अनुसार एक बार नहीं)। आपको इसके बजाय इनलाइन टेबल वैल्यू फ़ंक्शन को देखना चाहिए।
एरिक डार्लिंग

-2

बड़े डेटा पर फ़ंक्शन का उपयोग करने से लंबे निष्पादन समय लग सकता है। मेरे पास 8million पंक्तियों का डेटासेट है, जिसका उपयोग करने में 30 मिनट से अधिक समय लगता है। replace(replace(replace(replace(@COLUMN,CHAR(9),''),CHAR(10),''),CHAR(13),''),CHAR(32),'')केवल 5 सेकंड लिया। सबको शुक्रीया। मैं आपको @ sami.almasagedi और @Colin 't Hart देख रहा हूं


जैसा कि आप दोहरा रहे हैं उत्तर में, यह समस्या को हल नहीं करता है यदि पहले और अंतिम गैर-व्हाट्सएप पात्रों के बीच व्हाट्सएप को बनाए रखा जाना चाहिए। वांछित उत्तर में परिणाम आने पर ही गति उपयोगी है। इसके अलावा - कार्यों को इस तरह से एक क्वेरी को धीमा नहीं करना सुनिश्चित करने के तरीके पर स्वीकृत उत्तर में नोट्स देखें।
RDFozz
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.