Sqlserver
 sql >> Database >  >> RDS >> Sqlserver

Fascicolazione in SQL Server

Introduzione

Devi aver già sentito il termine "Fascicolazione" in SQL Server. Le regole di confronto sono una configurazione che determina il modo in cui viene eseguito l'ordinamento dei dati dei caratteri. Si tratta di un'impostazione importante che ha un enorme impatto sul comportamento del motore di database di SQL Server nella gestione dei dati dei caratteri. In questo articolo, intendiamo discutere le regole di confronto in generale e mostrare alcuni esempi di gestione delle regole di confronto.

Dove trovo le regole di confronto?

È possibile trovare le regole di confronto SQL a livello di server, database e colonna. Un'altra cosa importante da sapere è che l'impostazione delle regole di confronto non deve essere la stessa a livello di server, database e colonna. Inoltre, puoi aggiornare le tue query per utilizzare regole di confronto specifiche. È in questo momento che ti renderai conto dell'importanza di configurare le regole di confronto corrette nel tuo ambiente poiché esiste un'elevata possibilità di problemi imprevisti se le regole di confronto non sono coerenti.

Quali sono i diversi tipi di confronto disponibili?

Puoi ottenere l'elenco completo delle regole di confronto disponibili interrogando la funzione di sistema sys.fn_helpcollations()

select * from sys.fn_helpcollations()

Questo restituirà il seguente output.

Se stai cercando regole di confronto specifiche per lingua, puoi filtrare ulteriormente il nome. Ad esempio, se stai cercando le regole di confronto supportate dalla lingua Maori, puoi utilizzare la seguente query.

select * from sys.fn_helpcollations()
    where name like '%Maori%'

Questo restituirà il seguente output.

In questo modo puoi verificare le regole di confronto supportate per le regole di confronto di tua scelta. Solo interrogando la funzione di sistema fn_helpcollations(), sono state restituite 5508 righe in totale, il che significa che ci sono molte regole di confronto supportate. Tieni presente che questo copre la maggior parte delle lingue in tutto il mondo.

Quali sono le diverse opzioni che vedi nel nome della raccolta?

Ad esempio, in questa raccolta:Maori_100_CS_AI_KS_WS_SC_UTF8, puoi vedere le varie opzioni nel nome della raccolta.

CS – distinzione tra maiuscole e minuscole
AI – insensibile all'accento
KS – kana sensibile al tipo
WS – sensibile alla larghezza
SC – caratteri supplementari
UTF8 – Standard di codifica
In base al tipo di opzione di confronto selezionata, il motore di database di SQL Server funzionerà in modo diverso nella gestione dei dati dei caratteri per le operazioni di ordinamento e ricerca. Ad esempio, se si utilizza l'opzione con distinzione tra maiuscole e minuscole nelle regole di confronto SQL, il motore di database si comporterà in modo diverso per un'operazione di query che cerca "Adam" o "adam". Supponendo che tu abbia una tabella chiamata "campione" e che ci sia una colonna del nome con un utente "adam". La query seguente non restituirà risultati se non è presente alcuna riga con il nome "Adam". Ciò è dovuto all'opzione "CS-Maiuscole/minuscole" nelle regole di confronto.

select * from sample
    where firstname like '%Adam%'

Con questo semplice esempio, puoi comprendere il significato della scelta dell'opzione di confronto SQL corretta. Assicurati di aver compreso i requisiti dell'applicazione prima di selezionare le regole di confronto.

Trovare regole di confronto sull'istanza di SQL Server

È possibile ottenere le regole di confronto del server in SQL Server Management Studio (SSMS) facendo clic con il pulsante destro del mouse sull'istanza SQL, quindi facendo clic sull'opzione "Proprietà" e selezionando la scheda "Generale". Queste regole di confronto sono selezionate per impostazione predefinita durante l'installazione di SQL Server.

In alternativa, puoi utilizzare l'opzione serverproperty per trovare il valore di confronto.

select SERVERPROPERTY('collation'),

Trovare le regole di confronto di un database SQL

In SSMS, fai clic con il pulsante destro del mouse sul database SQL e vai su "Proprietà". Puoi controllare i dettagli della fascicolazione nella scheda "Generale" come mostrato di seguito.

In alternativa, puoi utilizzare la funzione databasepropertyex per ottenere i dettagli di una confronto di database.

select DATABASEPROPERTYEX('Your DB Name','collation')

Trovare le regole di confronto di una colonna in una tabella

In SSMS, vai alla tabella, quindi alle colonne e infine fai clic con il pulsante destro del mouse sulle singole colonne per visualizzare le "Proprietà". Se la colonna è di tipo dati carattere, vedrai i dettagli delle regole di confronto.

Tuttavia, allo stesso tempo, se si controlla il valore per un tipo di dati non carattere, il valore di confronto sarà nullo. Di seguito è riportato uno screenshot di una colonna con tipo di dati int.

In alternativa, puoi utilizzare una query di esempio di seguito per visualizzare i valori di confronto per le colonne.

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

Di seguito è riportato l'output per la query.

Prova di diverse regole di confronto nelle query SQL

In questa sezione, vedremo come l'ordinamento viene influenzato quando nelle query vengono utilizzate diverse regole di confronto. Viene creata una tabella di esempio con 2 colonne come mostrato di seguito.

La colonna fname ha le regole di confronto predefinite del database a cui appartiene. In questo caso, le regole di confronto sono SQL_Latin1_General_CP1_CI_AS.
Per inserire alcuni record nella tabella, utilizza una query di seguito. Assegna i tuoi valori ai parametri.

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')

Ora, interroga la tabella emp e ordinala in base alla colonna fname usando regole di confronto diverse. Utilizzeremo le regole di confronto predefinite della colonna per l'ordinamento e un'altra confronto con distinzione tra maiuscole e minuscole: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

L'output per queste query è riportato di seguito. Notare la differenza nelle regole di confronto utilizzate. Utilizziamo la distinzione tra maiuscole e minuscole anziché senza distinzione tra maiuscole e minuscole.

Puoi anche controllare i piani di query per entrambe queste query per individuare la differenza. Sul primo piano di query in cui utilizziamo un confronto diverso da quello nella colonna, puoi notare l'operatore aggiuntivo "Calcola scalare".

Quando passi il mouse sopra l'operatore "Compute Scalar", vedrai i dettagli aggiuntivi come mostrato di seguito. Ciò è dovuto alla conversione implicita che sta avvenendo poiché stiamo utilizzando una confronto diverso da quello predefinito utilizzato nella colonna.

Con questo piccolo esempio, puoi vedere il tipo di impatto sulle prestazioni delle query quando usi le regole di confronto in modo esplicito nelle query. Nel nostro database demo, abbiamo utilizzato una tabella semplice, ma immaginiamo uno scenario in tempo reale in cui piccoli cambiamenti nelle prestazioni delle query possono causare risultati imprevisti.

Verifica se è possibile modificare le regole di confronto a livello di istanza

In questa sezione esamineremo diversi scenari in cui potrebbe essere necessario modificare le regole di confronto predefinite. È possibile che si verifichino situazioni in cui server o database vengono consegnati a te e potrebbero non soddisfare le tue politiche standard, quindi potrebbe essere necessario modificare le regole di confronto. Le regole di confronto predefinite di SQL Server sono SQL_Latin1_General_CP1_CI_AS. La modifica delle regole di confronto a livello di istanza SQL non è semplice. Richiede lo scripting di tutti gli oggetti nei database utente, l'esportazione dei dati, l'eliminazione dei database utente, la ricostruzione del database master con le nuove regole di confronto, la creazione dei database utente e quindi l'importazione di tutti i dati. Quindi, se stai installando nuove istanze SQL, assicurati di avere le regole di confronto corrette la prima volta, altrimenti potresti dover fare molto lavoro indesiderato in seguito. Spiegare in dettaglio le fasi per modificare le regole di confronto a livello di istanza va oltre lo scopo di questo articolo a causa dei passaggi dettagliati richiesti per ciascuna fase.

Modifica delle regole di confronto a livello di database

Fortunatamente, modificare le regole di confronto a livello di database non è così difficile come modificare le regole di confronto dell'istanza. Possiamo aggiornare le regole di confronto utilizzando sia SSMS che T-SQL. In SSMS, fai clic con il pulsante destro del mouse sul database, vai su "Proprietà" e fai clic sulla scheda "Opzioni" sul lato sinistro. Lì puoi visualizzare l'opzione per modificare le regole di confronto nel menu a discesa.

Fare clic su "OK" una volta terminato. Ho appena cambiato le regole di confronto del database in SQL_Latin1_General_CP1_CI_AS. Assicurati solo di eseguire questa operazione quando il database non è in uso, altrimenti l'operazione fallirà come mostrato di seguito.

Utilizzare la query successiva per modificare le regole di confronto del database utilizzando T-SQL.

USE master;  
GO  
ALTER DATABASE mo  
COLLATE SQL_Latin1_General_CP1_CS_AS;  
GO

Si noterà che la modifica delle regole di confronto a livello di database non influirà sulle regole di confronto delle colonne esistenti nelle tabelle. Puoi utilizzare gli esempi precedenti per verificare l'impatto delle regole di confronto sull'ordinamento per le query seguenti.

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

Le regole di confronto delle colonne fname rimarranno quelle originali e rimarranno invariate anche dopo aver modificato le regole di confronto a livello di database.

Tuttavia, le nuove regole di confronto a livello di database verranno applicate a tutte le nuove colonne nelle nuove tabelle che creerai. Quindi, verifica sempre a fondo la modifica delle regole di confronto del database poiché ha un impatto considerevole sull'output o sul comportamento delle query.

Modifica delle regole di confronto a livello di colonna

Nella sezione precedente, hai notato che anche dopo aver modificato le regole di confronto a livello di database, le regole di confronto delle colonne esistenti nelle tabelle rimangono invariate. In questa sezione, vedremo come modificare le regole di confronto delle colonne esistenti nelle tabelle in modo che corrispondano a quelle del database. Nella sezione precedente, hai modificato le regole di confronto del database in SQL_Latin1_General_CP1_CS_AS. Successivamente, si desidera identificare tutte le colonne nelle tabelle utente che non corrispondono a queste regole di confronto del database. Puoi utilizzare questo script per identificare quelle colonne.

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'

L'output di esempio dal mio database demo è come mostrato di seguito.

Supponiamo di voler modificare le regole di confronto della colonna fname esistente in "SQL_Latin1_General_CP1_CS_AS", quindi puoi utilizzare questo script alter di seguito.

use mo
go
ALTER TABLE dbo.emp ALTER COLUMN fname  
            nvarchar(20) COLLATE SQL_Latin1_General_CP1_CS_AS NULL;  
GO

Se utilizzi gli esempi precedenti in cui hai verificato le prestazioni della query utilizzando regole di confronto diverse, noterai che l'operatore "calcola scalare" non viene utilizzato quando utilizziamo le stesse regole di confronto del database. Fare riferimento allo screenshot qui sotto. Nell'esempio precedente, potresti aver notato l'operatore "Compute scalare" utilizzato nel primo piano di esecuzione. Poiché abbiamo modificato le regole di confronto delle colonne in modo che corrispondano a quelle del database, non è necessaria la conversione implicita. Vedrai l'operatore "Calcola scalare" nella seconda query poiché utilizza esplicitamente regole di confronto diverse.

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

Possiamo modificare le regole di confronto dei database di sistema?

Non è possibile modificare le regole di confronto dei database di sistema. Se provi a modificare le regole di confronto dei database di sistema:master, model, msdb o tempdb, visualizzerai questo messaggio di errore.

Sarà necessario seguire i passaggi descritti in precedenza per modificare le regole di confronto a livello di istanza di SQL Server per modificare le regole di confronto dei database di sistema. È importante che le regole di confronto siano corrette la prima volta che si installa SQL Server per evitare tali problemi.

Il problema noto del conflitto di confronto

Un altro problema comune che potresti riscontrare è l'errore relativo al conflitto di confronto, specialmente durante l'utilizzo di oggetti temporanei. Gli oggetti temporanei vengono archiviati nel tempdb. Il tempdb essendo un database di sistema assumerà le regole di confronto dell'istanza SQL. Quando crei database utente con regole di confronto diverse da quella dell'istanza SQL, si verificheranno problemi durante l'utilizzo di oggetti temporanei. Potresti anche riscontrare problemi durante il confronto delle colonne nelle tabelle con regole di confronto diverse. A questo punto, sai già che una tabella può avere colonne con regole di confronto diverse poiché non possiamo modificare le regole di confronto a livello di tabella. Il messaggio di errore comune che noterai è qualcosa del tipo "Impossibile risolvere il conflitto di confronto tra "Fascicolazione1" e "Fascicolazione2" nell'operazione uguale a". Collation1 e Collation2 possono essere qualsiasi confronto utilizzato in una query. Utilizzando un semplice esempio, possiamo produrre una demo di questo conflitto di confronto. Se hai completato gli esempi precedenti in questo articolo, avrai già una tabella denominata "emp". Basta creare una tabella temporanea nel database demo e inserire i record utilizzando lo script di esempio fornito.

create table #emptemp
(id int,
 fname nvarchar(20))

insert into  #emptemp
select * from emp

Basta eseguire un join utilizzando entrambe le tabelle e otterrai questo errore di conflitto di confronto come mostrato di seguito.

select e.id, et.fname 
from emp e inner join #emptemp et
on e.fname=et.fname

Noterai che il confronto del database utente utilizzato è "SQL_Latin1_General_CP1_CS_AS" e non corrisponde a quello del confronto del server. Per correggere questo tipo di errore, è possibile modificare le colonne utilizzate negli oggetti temporanei per utilizzare le regole di confronto predefinite del database utente. È possibile utilizzare l'opzione "database_default" o fornire esplicitamente il nome di confronto del database utente. In questo esempio, utilizziamo le regole di confronto "SQL_Latin1_General_CP1_CS_AS". Prova una di queste opzioni
Opzione 1: Usa l'opzione database_default

alter table #emptemp alter column
 fname nvarchar(20) collate database_default

Al termine, esegui nuovamente l'istruzione select e l'errore verrà corretto.
Opzione 2: Usa le regole di confronto del database utente in modo esplicito

alter table #emptemp alter column
 fname nvarchar(20) collate SQL_Latin1_General_CP1_CS_AS

Al termine, esegui nuovamente l'istruzione select e l'errore verrà corretto.

Conclusione

In questo articolo, hai scoperto:
• il concetto di confronto
• le diverse opzioni di confronto disponibili
• la ricerca dei dettagli di confronto per qualsiasi istanza SQL, database e colonna
• A ESEMPIO DI LAVORO sulla prova delle opzioni di confronto nelle query SQL
• modifica delle regole di confronto a livello di istanza, a livello di database e a livello di colonna
• COME modificare le regole di confronto dei database di sistema
• un conflitto di regole di confronto e come per risolverlo

Ora conosci l'importanza delle regole di confronto e la criticità della configurazione delle regole di confronto corrette nell'istanza SQL e anche negli oggetti del database. Testare sempre i vari scenari nel proprio ambiente di test prima di applicare una delle opzioni di cui sopra ai sistemi di produzione.