Inleiding
U heeft vast al gehoord van de term "Collatie" in SQL Server. Sorteren is een configuratie die bepaalt hoe karaktergegevens worden gesorteerd. Dit is een belangrijke instelling die een enorme impact heeft op hoe de SQL Server-database-engine zich gedraagt bij het omgaan met tekengegevens. In dit artikel willen we sorteringen in het algemeen bespreken en enkele voorbeelden laten zien van het omgaan met sorteringen.
Waar vind ik sorteringen?
U vindt SQL-sortering op server-, database- en kolomniveau. Een ander belangrijk ding om te weten is dat de sorteerinstelling niet hetzelfde hoeft te zijn op server-, database- en kolomniveau. U kunt uw zoekopdrachten ook bijwerken om specifieke sorteringen te gebruiken. Op dit moment realiseert u zich hoe belangrijk het is om de juiste sortering in uw omgeving te configureren, aangezien er een grote kans is op onverwachte problemen als de sortering niet consistent is.
Wat zijn de verschillende soorten sorteringen die beschikbaar zijn?
U kunt de volledige lijst met beschikbare sorteringen verkrijgen door de systeemfunctie sys.fn_helpcollations()
op te vragen.select * from sys.fn_helpcollations()
Dit levert de volgende uitvoer op.
Als u specifieke sorteringen op taal zoekt, kunt u de naam verder filteren. Als u bijvoorbeeld zoekt naar de door de Maori-taal ondersteunde sortering, kunt u de volgende zoekopdracht gebruiken.
select * from sys.fn_helpcollations() where name like '%Maori%'
Dit levert de volgende uitvoer op.
Op deze manier kunt u de ondersteunde sorteringen controleren voor de sortering van uw keuze. Bij het opvragen van de systeemfunctie fn_helpcollations() werden in totaal 5508 rijen geretourneerd, wat betekent dat er zoveel ondersteunde sorteringen zijn. Merk op dat dit de meeste talen over de hele wereld omvat.
Wat zijn de verschillende opties die je ziet in de sorteernaam?
In deze sortering:Maori_100_CS_AI_KS_WS_SC_UTF8 ziet u bijvoorbeeld de verschillende opties in de sorteernaam.
CS – hoofdlettergevoelig
AI – accentongevoelig
KS – kana-typegevoelig
WS – breedtegevoelig
SC – aanvullende tekens
UTF8 – Coderingsstandaard
Op basis van het geselecteerde type sorteeroptie, zal de SQL Server-database-engine anders presteren bij het omgaan met tekengegevens voor sorteer- en zoekbewerkingen. Als u bijvoorbeeld de hoofdlettergevoelige optie in de SQL-sortering gebruikt, gedraagt de database-engine zich anders voor een querybewerking die zoekt naar "Adam" of "adam". Ervan uitgaande dat u een tabel hebt met de naam "sample" en dat er een voornaamkolom is met een gebruiker "adam". De onderstaande zoekopdracht levert geen resultaten op als er geen rij is met een voornaam "Adam". Dit komt door de "CS-Hoofdlettergevoelig" optie in de sortering.
select * from sample where firstname like '%Adam%'
Met dit eenvoudige voorbeeld begrijpt u hoe belangrijk het is om de juiste SQL-sorteeroptie te kiezen. Zorg ervoor dat u de toepassingsvereisten begrijpt voordat u sortering selecteert.
Collatie vinden op SQL Server-instantie
U kunt de serversortering verkrijgen in SQL Server Management Studio (SSMS) door met de rechtermuisknop op de SQL-instantie te klikken, vervolgens op de optie "Eigenschappen" te klikken en het tabblad "Algemeen" aan te vinken. Deze sortering is standaard geselecteerd bij de installatie van SQL Server.
U kunt ook de optie serverproperty gebruiken om de sorteerwaarde te vinden.
select SERVERPROPERTY('collation'),
Collatie van een SQL-database zoeken
Klik in SSMS met de rechtermuisknop op de SQL-database en ga naar "Eigenschappen". U kunt de sorteergegevens controleren op het tabblad 'Algemeen', zoals hieronder weergegeven.
Als alternatief kunt u de functie databasepropertyex gebruiken om de details van een databasesortering te krijgen.
select DATABASEPROPERTYEX('Your DB Name','collation')
Collatie van een kolom in een tabel zoeken
Ga in SSMS naar de tabel, vervolgens naar kolommen en klik ten slotte met de rechtermuisknop op de afzonderlijke kolommen om de "Eigenschappen" te bekijken. Als de kolom van het karaktergegevenstype is, ziet u details van de sortering.
Als u echter tegelijkertijd de waarde voor een gegevenstype zonder tekens controleert, is de sorteerwaarde null. Hieronder ziet u een screenshot van een kolom met het gegevenstype int.
U kunt ook een voorbeeldquery hieronder gebruiken om de sorteerwaarden voor kolommen te bekijken.
select sc.name, sc.collation_name from sys.columns sc inner join sys.tables t on sc.object_id=t.object_id where t.name='t1' – enter your table name
Hieronder vindt u de uitvoer voor de zoekopdracht.
Verschillende sorteringen uitproberen in SQL-query's
In deze sectie zullen we zien hoe de sorteervolgorde wordt beïnvloed wanneer verschillende sorteringen worden gebruikt in query's. Er wordt een voorbeeldtabel gemaakt met 2 kolommen zoals hieronder weergegeven.
De fname-kolom heeft de standaardsortering van de database waartoe deze behoort. In dit geval is de sortering SQL_Latin1_General_CP1_CI_AS.
Gebruik onderstaande query om enkele records in de tabel in te voegen. Wijs uw eigen waarden toe aan de parameters.
insert into emp values (1,'mohammed') insert into emp values (2,'moinudheen') insert into emp values (3,'Mohammed') insert into emp values (4,'Moinudheen') insert into emp values (5,'MOHAMMED') insert into emp values (6,'MOINUDHEEN')
Voer nu een query uit op de emp-tabel en sorteer deze op de fname-kolom met verschillende sorteringen. We zullen de standaardsortering van de kolom gebruiken om te sorteren, evenals een andere hoofdlettergevoelige sortering - SQL_Latin1_General_CP1_CS_AS.
select * from emp order by fname collate SQL_Latin1_General_CP1_CS_AS select * from emp order by fname collate SQL_Latin1_General_CP1_CI_AS – this is default
De output voor deze queries wordt hieronder gegeven. Let op het verschil in gebruikte sortering. We gebruiken hoofdlettergevoelig in plaats van hoofdletterongevoelig.
U kunt ook de queryplannen voor beide query's controleren om het verschil te zien. Op het eerste queryplan waarbij we een andere sortering gebruiken dan die in de kolom, ziet u de extra operator 'Compute Scalar'.
Wanneer u de muisaanwijzer over de operator "Compute Scalar" beweegt, ziet u de aanvullende details zoals hieronder weergegeven. Dit komt door de impliciete conversie die plaatsvindt, omdat we een andere sortering gebruiken dan de standaard die in de kolom wordt gebruikt.
Met dit kleine voorbeeld kunt u het soort impact op de queryprestaties zien wanneer u sorteringen expliciet in query's gebruikt. In onze demodatabase hebben we een eenvoudige tabel gebruikt, maar stel je een realtime scenario voor waarin kleine veranderingen in de queryprestaties onverwachte resultaten kunnen veroorzaken.
Controleren of het mogelijk is om de sortering op instantieniveau te wijzigen
In deze sectie zullen we verschillende scenario's bekijken waarin we de standaardsorteringen mogelijk moeten wijzigen. U kunt situaties tegenkomen waarbij servers of databases aan u worden overgedragen en ze mogelijk niet voldoen aan uw standaardbeleid, dus het kan zijn dat u de sortering moet wijzigen. De standaard SQL Server-sortering is SQL_Latin1_General_CP1_CI_AS. Het wijzigen van de sortering op SQL-instantieniveau is niet eenvoudig. Het vereist het scripten van alle objecten in de gebruikersdatabases, het exporteren van de gegevens, het verwijderen van de gebruikersdatabases, het opnieuw opbouwen van de hoofddatabase met de nieuwe sortering, het maken van de gebruikersdatabases en het importeren van alle gegevens. Dus als u nieuwe SQL-instanties installeert, zorg er dan voor dat u de eerste keer de juiste sortering uitvoert, anders moet u later mogelijk veel ongewenst werk doen. Het in detail uitleggen van de fasen voor het wijzigen van sortering op instantieniveau valt buiten het bestek van dit artikel vanwege de gedetailleerde stappen die nodig zijn voor elk van de fasen.
Collatie wijzigen op databaseniveau
Gelukkig is het wijzigen van de sortering op databaseniveau niet zo moeilijk als het wijzigen van de sortering van de instantie. We kunnen de sortering bijwerken met zowel SSMS als T-SQL. Klik in SSMS met de rechtermuisknop op de database, ga naar "Eigenschappen" en klik op het tabblad "Opties" aan de linkerkant. Daar kun je de optie bekijken om de sortering te wijzigen in het vervolgkeuzemenu.
Klik op "OK" als u klaar bent. Ik heb zojuist de database-sortering gewijzigd in SQL_Latin1_General_CP1_CI_AS. Zorg ervoor dat u deze bewerking uitvoert wanneer de database niet in gebruik is, anders mislukt de bewerking, zoals hieronder wordt weergegeven.
Gebruik de vervolgquery om de databasesortering te wijzigen met behulp van T-SQL.
USE master; GO ALTER DATABASE mo COLLATE SQL_Latin1_General_CP1_CS_AS; GO
U zult merken dat het wijzigen van de sortering op databaseniveau geen invloed heeft op de sortering van de bestaande kolommen in de tabellen. U kunt de eerdere voorbeelden gebruiken om de impact van sortering op de sorteervolgorde voor de onderstaande zoekopdrachten te controleren.
select * from emp order by fname collate SQL_Latin1_General_CP1_CS_AS select * from emp order by fname collate SQL_Latin1_General_CP1_CI_AS – - this is default
De sortering van de fname-kolom blijft de originele en blijft ongewijzigd, zelfs nadat de sortering op databaseniveau is gewijzigd.
De nieuwe sortering op databaseniveau wordt echter toegepast op alle nieuwe kolommen in de nieuwe tabellen die u gaat maken. Test het wijzigen van databasesorteringen daarom altijd grondig, aangezien dit een aanzienlijke invloed heeft op de uitvoer of het gedrag van query's.
Collatie wijzigen op kolomniveau
In de vorige sectie heeft u opgemerkt dat zelfs na het wijzigen van de sortering op databaseniveau, de sortering van de bestaande kolommen in de tabellen ongewijzigd blijft. In deze sectie zullen we zien hoe we de sortering van de bestaande kolommen in de tabellen kunnen wijzigen zodat deze overeenkomen met die van de database-sortering. In de vorige sectie hebt u de databasesortering gewijzigd in SQL_Latin1_General_CP1_CS_AS. Vervolgens wilt u alle kolommen in de gebruikerstabellen identificeren die niet overeenkomen met deze databasesortering. U kunt dit script gebruiken om die kolommen te identificeren.
select so.name TableName,sc.name ColumnName, sc.collation_name CollationName from sys.objects so inner join sys.columns sc on so.object_id=sc.object_id where sc.collation_name!='SQL_Latin1_General_CP1_CS_AS' and so.[type] ='U'
De voorbeelduitvoer van mijn demo-database is zoals hieronder weergegeven.
Stel dat u de sortering van de bestaande fname-kolom wilt wijzigen in "SQL_Latin1_General_CP1_CS_AS", dan kunt u dit alter-script hieronder gebruiken.
use mo go ALTER TABLE dbo.emp ALTER COLUMN fname nvarchar(20) COLLATE SQL_Latin1_General_CP1_CS_AS NULL; GO
Als u de eerdere voorbeelden gebruikt waarin u de queryprestaties hebt gecontroleerd met verschillende sorteringen, zult u merken dat de operator "bereken scalaire" niet wordt gebruikt wanneer we dezelfde sortering gebruiken als die van de database. Raadpleeg de onderstaande schermafbeelding. In het eerdere voorbeeld had u kunnen zien dat de "Compute scalar"-operator werd gebruikt in het eerste uitvoeringsplan. Omdat we de kolomsortering hebben gewijzigd zodat deze overeenkomt met die van de databasesortering, is impliciete conversie niet nodig. U ziet de operator "Scalaire berekening" in de tweede query omdat deze expliciet een andere sortering gebruikt.
select * from emp order by fname collate SQL_Latin1_General_CP1_CS_AS – - this is default select * from emp order by fname collate SQL_Latin1_General_CP1_CI_AS
Kunnen we de sortering van systeemdatabases wijzigen?
Het is niet mogelijk om de sortering van systeemdatabases te wijzigen. Als u de sortering van de systeemdatabases probeert te wijzigen - master, model, msdb of tempdb, krijgt u deze foutmelding.
U moet de eerder beschreven stappen voor het wijzigen van de sortering op SQL Server-instantieniveau volgen om de sortering van de systeemdatabases te wijzigen. Het is belangrijk dat de sorteringen correct zijn wanneer u SQL Server de eerste keer installeert om dergelijke problemen te voorkomen.
Het bekende probleem over sorteerconflicten
Een ander veelvoorkomend probleem dat u kunt tegenkomen, is de fout met betrekking tot sorteerconflicten, vooral bij het gebruik van tijdelijke objecten. De tijdelijke objecten worden opgeslagen in de tempdb. Aangezien tempdb een systeemdatabase is, wordt de sortering van de SQL-instantie aangenomen. Wanneer u gebruikersdatabases maakt die een andere sortering hebben dan die van de SQL-instantie, zult u problemen tegenkomen bij het gebruik van tijdelijke objecten. U kunt ook problemen ondervinden bij het vergelijken van kolommen in tabellen met verschillende sorteringen. U weet inmiddels al dat een tabel kolommen met verschillende sorteringen kan hebben, aangezien we de sortering niet op tabelniveau kunnen wijzigen. Het algemene foutbericht dat u zult opmerken, is zoiets als "Kan het sorteerconflict tussen "Collatie1" en "Collatie2" niet oplossen in de gelijk aan bewerking." Collation1 en Collation2 kunnen elke sortering zijn die in een query wordt gebruikt. Aan de hand van een eenvoudig voorbeeld kunnen we een demo maken van dit sorteerconflict. Als je de vorige voorbeelden in dit artikel hebt voltooid, heb je al een tabel met de naam "emp". Maak gewoon een tijdelijke tabel in uw demo-database en voeg records in met behulp van het meegeleverde voorbeeldscript.
create table #emptemp (id int, fname nvarchar(20)) insert into #emptemp select * from emp
Voer gewoon een join uit met beide tabellen en u krijgt deze sorteerconflictfout zoals hieronder weergegeven.
select e.id, et.fname from emp e inner join #emptemp et on e.fname=et.fname
U zult merken dat de gebruikte sortering van de gebruikersdatabase "SQL_Latin1_General_CP1_CS_AS" is en niet overeenkomt met die van de serversortering. Om dit type fout op te lossen, kunt u de kolommen die in de tijdelijke objecten worden gebruikt, wijzigen om de standaardsortering van de gebruikersdatabase te gebruiken. U kunt de optie "database_default" gebruiken of expliciet de sorteernaam van de gebruikersdatabase opgeven. In dit voorbeeld gebruiken we de sortering "SQL_Latin1_General_CP1_CS_AS". Probeer een van deze opties
Optie 1: Gebruik de database_default optie
alter table #emptemp alter column fname nvarchar(20) collate database_default
Als u klaar bent, voert u de select-instructie opnieuw uit en de fout wordt verholpen.
Optie 2: Gebruik expliciet de sortering van de gebruikersdatabase
alter table #emptemp alter column fname nvarchar(20) collate SQL_Latin1_General_CP1_CS_AS
Als u klaar bent, voert u de select-opdracht opnieuw uit en de fout wordt verholpen.
Conclusie
In dit artikel heeft u informatie gevonden over:
• het concept van sortering
• de verschillende beschikbare sorteeropties
• het vinden van sorteerdetails voor elke SQL-instantie, database en kolom
• Een WERKVOORBEELD over het uitproberen van sorteeropties in SQL-query's
• het wijzigen van sorteringen op instantieniveau, databaseniveau en kolomniveau
• HOE wijzig ik sorteringen van systeemdatabases
• een sorteerconflict en hoe om het te repareren
Nu weet u hoe belangrijk het is om te sorteren en hoe belangrijk het is om de juiste sortering te configureren voor de SQL-instantie en ook voor de database-objecten. Test altijd de verschillende scenario's op uw testomgeving voordat u een van de bovenstaande opties op uw productiesystemen toepast.