यहाँ ध्यान देने योग्य कुछ बातें हैं:
-
यदि आप यह देखना चाहते हैं कि वास्तव में कौन सा वर्ण है, तो आप मान को
VARBINARY
. में बदल सकते हैं जो आपको स्ट्रिंग में सभी वर्णों का हेक्स/बाइनरी मान देगा और हेक्स में "छिपे हुए" वर्णों की कोई अवधारणा नहीं है:DECLARE @PostalCode NVARCHAR(20); SET @PostalCode = N'053000'+ NCHAR(0x2008); -- 0x2008 = "Punctuation Space" SELECT @PostalCode AS [NVarCharValue], CONVERT(VARCHAR(20), @PostalCode) AS [VarCharValue], CONVERT(VARCHAR(20), RTRIM(@PostalCode)) AS [RTrimmedVarCharValue], CONVERT(VARBINARY(20), @PostalCode) AS [VarBinaryValue];
रिटर्न:
NVarCharValue VarCharValue RTrimmedVarCharValue VarBinaryValue 053000 053000? 053000? 0x3000350033003000300030000820
NVARCHAR
डेटा को यूटीएफ -16 के रूप में संग्रहीत किया जाता है जो 2-बाइट सेट में काम करता है। छिपे हुए 2-बाइट सेट को देखने के लिए अंतिम 4 हेक्स अंकों को देखते हुए, हम "0820" देखते हैं। चूंकि विंडोज और एसक्यूएल सर्वर यूटीएफ -16 लिटिल एंडियन (यानी यूटीएफ -16 एलई) हैं, बाइट रिवर्स ऑर्डर में हैं। अंतिम 2 बाइट्स फ़्लिप करना --08
और20
-- हमें "2008" मिलता है, जो कि "विराम चिह्न स्थान" है जिसे हमनेNCHAR(0x2008)
के माध्यम से जोड़ा है ।साथ ही, कृपया ध्यान दें कि
RTRIM
यहाँ बिल्कुल भी मदद नहीं की। -
सरल तरीके से, आप केवल प्रश्नवाचक चिह्नों को कुछ भी नहीं से बदल सकते हैं:
SELECT REPLACE(CONVERT(VARCHAR(20), [PostalCode]), '?', '');
-
इससे भी महत्वपूर्ण बात यह है कि आपको
[PostalCode]
. को रूपांतरित करना चाहिएVARCHAR
. पर फ़ील्ड करें ताकि यह इन पात्रों को संग्रहीत न करे। कोई भी देश ऐसे अक्षरों का उपयोग नहीं करता है जो ASCII वर्ण सेट में प्रदर्शित नहीं होते हैं और जो VARCHAR डेटाटाइप के लिए मान्य नहीं हैं, कम से कम जहाँ तक मैंने कभी पढ़ा है (संदर्भों के लिए नीचे अनुभाग देखें)। वास्तव में, जो अनुमति है वह ASCII का एक छोटा उपसमुच्चय है, जिसका अर्थ है कि आप रास्ते में आसानी से फ़िल्टर कर सकते हैं (या बस वही करेंREPLACE
जैसा कि डालने या अपडेट करते समय ऊपर दिखाया गया है):ALTER TABLE [table] ALTER COLUMN [PostalCode] VARCHAR(20) [NOT]? NULL;
वर्तमान
NULL
. की जांच करना सुनिश्चित करें /NOT NULL
कॉलम के लिए सेटिंग और इसे ऊपर दिए गए ALTER स्टेटमेंट में समान बनाएं, अन्यथा इसे बदला जा सकता है क्योंकि डिफ़ॉल्टNULL
है यदि निर्दिष्ट नहीं है। -
यदि आप तालिका के स्कीमा को नहीं बदल सकते हैं और खराब डेटा की आवधिक "सफाई" करने की आवश्यकता है, तो आप निम्न चला सकते हैं:
;WITH cte AS ( SELECT * FROM TableName WHERE [PostalCode] <> CONVERT(NVARCHAR(50), CONVERT(VARCHAR(50), [PostalCode])) ) UPDATE cte SET cte.[PostalCode] = REPLACE(CONVERT(VARCHAR(50), [PostalCode]), '?', '');
कृपया ध्यान रखें कि यदि तालिका में लाखों पंक्तियाँ हैं तो उपरोक्त क्वेरी कुशलता से काम करने के लिए नहीं है। उस समय इसे लूप के माध्यम से छोटे सेटों में हैंडल करने की आवश्यकता होगी।
संदर्भ के लिए, यहां डाक कोड के लिए विकिपीडिया लेख है। , जो वर्तमान में बताता है कि केवल वही वर्ण जो कभी उपयोग किए गए हैं:
और क्षेत्र के अधिकतम आकार के संबंध में, यहां विकिपीडिया डाक कोड की सूची है।