एक अन्य विकल्प SQLCLR के माध्यम से इसे संभालना है। .NET में पहले से ही एक विधि उपलब्ध है जो ऐसा करती है: TextInfo.ToTitleCase (इन System.Globalization
)। यह विधि प्रत्येक शब्द के पहले अक्षर को अपर-केस करेगी, और शेष अक्षरों को लोअर-केस। यहां अन्य प्रस्तावों के विपरीत, यह उन शब्दों को भी छोड़ देता है, जो सभी ऊपरी मामलों में हैं, उन्हें समरूप मानते हैं। बेशक, यदि यह व्यवहार वांछित है, तो ऐसा करने के लिए किसी भी टी-एसक्यूएल सुझाव को अपडेट करना काफी आसान होगा।
.NET पद्धति का एक लाभ यह है कि यह अपर-केस अक्षर हैं जो अनुपूरक वर्ण हैं। उदाहरण के लिए: DESERET SMALL LETTER OW में DESERET CAPITAL LETTER OW का ऊपरी-मामला मानचित्रण है (दोनों जब मैं यहां चिपकाता हूं तो बक्से के रूप में दिखाई देता है) , लेकिन UPPER()
फ़ंक्शन लोअर-केस संस्करण को ऊपरी-केस में नहीं बदलता है, तब भी वर्तमान डेटाबेस के लिए डिफ़ॉल्ट Collation सेट है Latin1_General_100_CI_AS_SC
। यह MSDN प्रलेखन के साथ संगत लगता है जो सूचीबद्ध नहीं करता है UPPER
और LOWER
फ़ंक्शन के चार्ट में जो एक _SC
Collation का उपयोग करते समय अलग तरीके से व्यवहार करते हैं : Collation और यूनिकोड समर्थन: अनुपूरक वर्ण ।
SELECT N'DESERET SMALL LETTER OW' AS [Label], NCHAR(0xD801)+NCHAR(0xDC35) AS [Thing]
UNION ALL
SELECT N'DESERET CAPITAL LETTER OW' AS [Label], NCHAR(0xD801)+NCHAR(0xDC0D) AS [Thing]
UNION ALL
SELECT N'SmallButShouldBeCapital' AS [Label], UPPER(NCHAR(0xD801)+NCHAR(0xDC35)) AS [Thing]
रिटर्न (बढ़े हुए आप वास्तव में अनुपूरक चरित्र देख सकते हैं):
आप निम्न-वर्णों की पूरी (और वर्तमान) सूची देख सकते हैं, जो कि यूनिकोड.ऑर्ग पर निम्न खोज सुविधा का उपयोग करके अपर-केस में बदल जाती हैं (जब तक आप "DESERET" प्राप्त नहीं कर लेते, आप नीचे स्क्रॉल करके अनुपूरक वर्ण देख सकते हैं) अनुभाग, या बस हिट Control-Fऔर उस शब्द के लिए खोज):
http://unicode.org/cldr/utility/list-unicodeset.jsp?a=%5B%3AChanges_When_Titlecased%3DYes%3A%5D
हालांकि ईमानदार होने के लिए, यह बहुत बड़ा लाभ नहीं है क्योंकि यह संदिग्ध है कि कोई भी वास्तव में पूरक वर्णों में से किसी का उपयोग कर रहा है जो शीर्षक-आवरण हो सकता है। किसी भी तरह से, यहाँ SQLCLR कोड है:
using System.Data.SqlTypes;
using System.Globalization;
using Microsoft.SqlServer.Server;
public class TitleCasing
{
[return: SqlFacet(MaxSize = 4000)]
[Microsoft.SqlServer.Server.SqlFunction(IsDeterministic = true, IsPrecise = true)]
public static SqlString TitleCase([SqlFacet(MaxSize = 4000)] SqlString InputString)
{
TextInfo _TxtInf = new CultureInfo(InputString.LCID).TextInfo;
return new SqlString (_TxtInf.ToTitleCase(InputString.Value));
}
}
यहाँ @ MikaelEriksson का सुझाव है - NVARCHAR
डेटा को संभालने के लिए थोड़ा संशोधित किया गया है और साथ ही उन शब्दों को छोड़ें जो सभी ऊपरी मामले हैं (.NET विधि के व्यवहार के अधिक निकटता से मेल खाते हैं) - साथ ही उस टी-एसक्यूएल कार्यान्वयन का परीक्षण और SQLCLR कार्यान्वयन:
SET NOCOUNT ON;
DECLARE @a NVARCHAR(50);
SET @a = N'qWeRtY kEyBoArD TEST<>&''"X one&TWO '
+ NCHAR(0xD801)+NCHAR(0xDC28)
+ N'pPLe '
+ NCHAR(0x24D0) -- ⓐ Circled "a"
+ NCHAR(0xFF24) -- D Full-width "D"
+ N'D u'
+ NCHAR(0x0308) -- ̈ (combining diaeresis / umlaut)
+ N'vU'
+ NCHAR(0x0308) -- ̈ (combining diaeresis / umlaut)
+ N'lA';
SELECT @a AS [Original];
SELECT STUFF((
SELECT N' '
+ IIF(UPPER(T3.V) <> T3.V COLLATE Latin1_General_100_BIN2,
UPPER(LEFT(T3.V COLLATE Latin1_General_100_CI_AS_SC, 1))
+ LOWER(STUFF(T3.V COLLATE Latin1_General_100_CI_AS_SC, 1, 1, N'')),
T3.V)
FROM (SELECT CAST(REPLACE((SELECT @a AS N'*' FOR XML PATH('')), N' ', N'<X/>')
AS XML).query('.')) AS T1(X)
CROSS APPLY T1.X.nodes('text()') AS T2(X)
CROSS APPLY (SELECT T2.X.value('.', 'NVARCHAR(70)')) AS T3(V)
FOR XML PATH(''), TYPE
).value('text()[1]', 'NVARCHAR(70)') COLLATE Latin1_General_100_CI_AS_SC, 1, 1, N'')
AS [Capitalize first letter only];
SELECT dbo.TitleCase(@a) AS [ToTitleCase];
व्यवहार में एक और अंतर यह है कि यह विशेष टी-एसक्यूएल कार्यान्वयन केवल रिक्त स्थान पर विभाजित होता है, जबकि ToTitleCase()
विधि शब्द गैर-अक्षर को शब्द विभाजक मानता है (इसलिए "एक और दो" भाग से निपटने में अंतर)।
दोनों कार्यान्वयन अनुक्रमों के संयोजन को सही ढंग से संभालते हैं। "Üv thelA" में उच्चारण अक्षरों में से प्रत्येक में एक आधार पत्र और एक संयोजन डायअरेसिस / umlaut (प्रत्येक अक्षर के ऊपर दो बिंदु) शामिल हैं, और वे दोनों परीक्षणों में अन्य मामले में सही रूप से परिवर्तित होते हैं।
अंत में, SQLCLR संस्करण के लिए एक अप्रत्याशित नुकसान यह है कि विभिन्न परीक्षणों के साथ आने पर, मुझे .NET कोड में एक बग मिला है, जो सर्कुलेटेड लेटर्स से निपटने से संबंधित है (जो अब Microsoft कनेक्ट - UPDATE को सूचित किया गया है: कनेक्ट किया गया है। स्थानांतरित करने के लिए /dev/null
- वस्तुतः - तो मुझे इसे फिर से जमा करने की आवश्यकता हो सकती है यदि समस्या अभी भी मौजूद है)। .NET लाइब्रेरी सर्किल लेटर्स को शब्द विभाजक के रूप में मानती है, यही कारण है कि इसे "ⓐDD" को ""d" में नहीं बदलना चाहिए जैसा कि इसे करना चाहिए।
FYI करें
TextInfo.ToTitleCase
उपर्युक्त विधि को एनक्लोज करने वाला एक पूर्व-निर्मित SQLCLR फ़ंक्शन अब SQL # (जो मैंने लिखा था) String_ToTitleCase और String_ToTitleCase4k के फ्री संस्करण में उपलब्ध है ।
😺