Eine andere Möglichkeit besteht darin, dies über SQLCLR zu handhaben. Es gibt sogar eine Methode, die in .NET bereits verfügbar ist: TextInfo.ToTitleCase (inSystem.Globalization
). Bei dieser Methode wird der erste Buchstabe jedes Wortes in Großbuchstaben und die verbleibenden Buchstaben in Kleinbuchstaben geschrieben. Im Gegensatz zu den anderen Vorschlägen werden hier auch Wörter übersprungen, bei denen es sich um Akronyme handelt. Wenn dieses Verhalten gewünscht wird, ist es natürlich einfach genug, einen der T-SQL-Vorschläge zu aktualisieren, um dies ebenfalls zu tun.
Ein Vorteil der .NET-Methode besteht darin, dass es sich bei Großbuchstaben um Zusatzzeichen handelt. Beispiel: DESERET SMALL LETTER OW enthält eine Zuordnung von DESERET CAPITAL LETTER OW in Großbuchstaben (beide werden als Kästchen angezeigt, wenn ich sie hier einfüge ) , aber die UPPER()
Funktion ändert die Kleinbuchstabenversion nicht in Großbuchstaben, selbst wenn Die Standardkollatierung für die aktuelle Datenbank ist auf festgelegt Latin1_General_100_CI_AS_SC
. Dies scheint mit der MSDN-Dokumentation übereinzustimmen, in der Funktionen, die sich bei Verwendung einer Kollatierung anders verhalten, nicht aufgelistet UPPER
und LOWER
in der Tabelle nicht aufgeführt sind _SC
: Kollatierung und Unicode-Unterstützung: Zusatzzeichen .
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]
Rückgabe (vergrößert, damit Sie das Zusatzzeichen tatsächlich sehen können):
Mit der folgenden Suchfunktion bei Unicode.org können Sie die vollständige (und aktuelle) Liste der Kleinbuchstaben anzeigen und in Großbuchstaben ändern. Abschnitt, oder drücken Sie einfach Control-Fund suchen Sie nach diesem Wort):
http://unicode.org/cldr/utility/list-unicodeset.jsp?a=%5B%3AChanges_When_Titlecased%3DYes%3A%5D
Obwohl dies, um ehrlich zu sein, kein großer Vorteil ist, da es zweifelhaft ist, dass tatsächlich jemand einen der Zusatzcharaktere verwendet, die mit einem Titel versehen werden können. In beiden Fällen ist hier der SQLCLR-Code:
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));
}
}
Hier ist der Vorschlag von @ MikaelEriksson - leicht modifiziert, um NVARCHAR
Daten zu verarbeiten sowie Wörter zu überspringen, die alle in Großbuchstaben geschrieben sind (um dem Verhalten der .NET-Methode besser zu entsprechen) - zusammen mit einem Test dieser T-SQL-Implementierung und von die SQLCLR-Implementierung:
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];
Ein weiterer Unterschied im Verhalten besteht darin, dass diese spezielle T-SQL-Implementierung sich nur auf Leerzeichen aufteilt, wohingegen die ToTitleCase()
Methode die meisten Nicht-Buchstaben als Worttrennzeichen betrachtet (daher der Unterschied in der Behandlung des "one & TWO" -Teils).
Beide Implementierungen behandeln das korrekte Kombinieren von Sequenzen. Jeder der akzentuierten Buchstaben in "üvÜlA" besteht aus einem Grundbuchstaben und einer Kombination aus Diaeresis / Umlaut (die beiden Punkte über jedem Buchstaben) und wird in beiden Tests korrekt in den anderen Fall umgewandelt.
Schließlich ist ein unerwarteter Nachteil der SQLCLR-Version, dass ich bei der Entwicklung verschiedener Tests einen Fehler im .NET-Code gefunden habe, der mit der Behandlung der eingekreisten Buchstaben zusammenhängt (was jetzt der Fall war) Microsoft Connect gemeldet wurde - UPDATE: Connect war verschoben nach /dev/null
- im wahrsten Sinne des Wortes -, daher muss ich dies möglicherweise erneut einreichen, wenn das Problem weiterhin besteht. Die .NET-Bibliothek behandelt die eingekreisten Buchstaben als Worttrennzeichen, weshalb das "ⓐDD" nicht wie gewünscht in "Ⓐdd" umgewandelt wird.
Zu Ihrer Information
Eine vorgefertigte SQLCLR-Funktion, die TextInfo.ToTitleCase
die oben erwähnte Methode kapselt, ist jetzt in der freien Version von SQL # (die ich geschrieben habe) als String_ToTitleCase verfügbar und String_ToTitleCase4k verfügbar .
😺