2010-09-20 25 views
5

मैं टेबल के लिए टी-एसक्यूएल चयन विवरण उत्पन्न कर रहा हूं जिसके लिए मेरे पास डेटा प्रकार की जानकारी सामने नहीं है। इन बयानों में, मुझे स्ट्रिंग मैनिपुलेशन ऑपरेशन करने की आवश्यकता है जो टेबल के कॉलम के मूल मान की लंबाई पर निर्भर करता है।टी-एसक्यूएल: अक्षरों में स्ट्रिंग की सटीक लंबाई कैसे प्राप्त करें?

एक उदाहरण है (न कि केवल एक) अंत में सम्मिलित करने का विकल्प भी शामिल है, एक स्ट्रिंग में एक विशिष्ट स्थान पर कुछ पाठ डालने के लिए है:

SELECT 
    CASE WHEN (LEN ([t0].[Product] = 8) 
    THEN [t0].[Product] + 'test' 
    ELSE STUFF ([t0].[Product], 8, 0, 'test') 
    END 
FROM [OrderItem] [t0] 

(मामला है जब + LEN है की आवश्यकता है क्योंकि STUFF मुझे एक स्ट्रिंग के अंत में पाठ डालने के लिए।)

समस्या यह है कि LEN अनुगामी रिक्त स्थान है, जो गणना को बर्बाद होगा शामिल नहीं है की अनुमति नहीं है। मैं जानता हूँ कि मैं DATALENGTH, जो रिक्त स्थान अनुगामी को अलग नहीं करता उपयोग कर सकते हैं, लेकिन मैं क्योंकि मैं नहीं पता कि उत्पाद स्तंभ प्रकार varchar या nvarchar की है बाइट्स STUFF के लिए आवश्यक वर्णों तक DATALENGTH द्वारा वापस नहीं बदल सकते।

तो, कैसे मैं एक एसक्यूएल बयान है कि सामने स्ट्रिंग डेटा प्रकार के बारे में जानकारी का उपयोग किया जा रहा है बिना पात्रों में एक स्ट्रिंग की सटीक लंबाई पर निर्भर करता है उत्पन्न कर सकते हैं?

उत्तर

12

यहाँ मैं का उपयोग कर समाप्त हो गया है:

SELECT 
    CASE WHEN ((LEN ([t0].[Product] + '#') - 1) = 8) 
    THEN [t0].[Product] + 'test' 
    ELSE STUFF ([t0].[Product], 8, 0, 'test') 
    END 
FROM [OrderItem] [t0] 

माप संकेत मिलता है कि LEN (। .. + '#') - 1 चाल अकेले गति (...) के समान गति के बारे में है।

सब अच्छा जवाब के लिए धन्यवाद!

+0

+1 जो समाधान के लिए काम करता है! –

+0

+1 यह एक उपयोगी चाल हो सकता है। –

3

आप सिस्टम टेबल में स्तंभों के लिए प्रकार की जानकारी को देखने नहीं कर सकते?

यदि यह निर्धारित करने के लिए कि कोई कॉलम varchar या nvarchar है तो यह ऐसा करेगा।

create table #test 
(
c varchar(50), 
n nvarchar(50) 
) 

insert into #test values ('1,2,3,4 ',N'1,2,3,4,5  ') 

SELECT 
     CASE 
       WHEN datalength(CAST(c AS nvarchar(MAX))) = datalength(c) 
       THEN 'c is nvarchar' 
       ELSE 'c is char' 
     END, 
     CASE 
       WHEN datalength(CAST(n AS nvarchar(MAX))) = datalength(n) 
       THEN 'n is nvarchar' 
       ELSE 'n is char' 
     END 
FROM #test 
+0

जानकारी देख रहे हैं: शायद संभव है, लेकिन मुश्किल है। मुझे यह भी यकीन नहीं है कि यह कैसे करेगा। –

+0

परीक्षण भी दिलचस्प है, लेकिन मुझे लगता है कि मुझे परिणामस्वरूप कथन की "पठनीयता" के संबंध में रिपप्लेस हैक थोड़ा बेहतर पसंद है। –

+0

@ फ़ैबियन - मैं निश्चित रूप से देख रहा हूं कि प्रकार की जानकारी कॉलम में प्रत्येक स्ट्रिंग या प्रत्येक स्ट्रिंग पर एक कलाकार पर प्रतिस्थापन करने से बेहतर प्रदर्शन करेगी। –

4

कोशिश यह:

SELECT 
    CASE WHEN (LEN (REPLACE([t0].[Product],' ', '#') = 8) 
    THEN [t0].[Product] + 'test' 
    ELSE STUFF ([t0].[Product], 8, 0, 'test') 
    END 
FROM [OrderItem] [t0] 
+0

अच्छा विचार, मुझे यह खुद होना चाहिए था ... –

+0

यह बहुत अक्षम है, क्योंकि मेरे माप दिखाते हैं। –

+1

हालांकि, इसकी तेज गति बिजली के रूप में तेज़ है: एलईएन ([टी 0]। [उत्पाद] + '#') - 1 यह अकेले एलईएन ([टी 0]। [उत्पाद]) की गति के बारे में है। .. –

1

उपयोग DATALENGTH और SQL_VARIANT_PROPERTY:

SELECT 
    CASE 
    WHEN 8 
     = DATALENGTH([t0].[Product]) 
    /CASE SQL_VARIANT_PROPERTY([t0].[Product],'BaseType') WHEN 'nvarchar' THEN 2 ELSE 1 END 
    THEN [t0].[Product] + 'test' 
    ELSE STUFF ([t0].[Product], 8, 0, 'test') 
    END 
FROM [OrderItem] [t0] 
+0

मैंने इसका परीक्षण किया है, और जब यह बिल्कुल मेरी तरह दिखता है, यह वर्चर (अधिकतम)/nvarchar (अधिकतम) के साथ काम नहीं करता है - क्योंकि sql_variant ऐसे मान नहीं रख सकता है। –

0

कोई प्रमुख कारतूस देखते हैं, तो len(reverse(column_name)) आप स्तंभ की लंबाई दे देंगे।