SQL Server verifica la distinzione tra maiuscole e minuscole?
-
05-07-2019 - |
Domanda
Come posso verificare se un database in SQL Server fa distinzione tra maiuscole e minuscole? In precedenza ho eseguito la query:
SELECT CASE WHEN 'A' = 'a' THEN 'NOT CASE SENSITIVE' ELSE 'CASE SENSITIVE' END
Ma sto cercando altri modi in quanto questo mi ha effettivamente dato problemi in passato.
Modifica - Altre informazioni:
Un prodotto esistente ha molte stored procedure pre-scritte. In una procedura memorizzata @test != @TEST
a seconda della sensibilità del server stesso. Quindi quello che sto cercando è il modo migliore per verificare la sensibilità del server.
Soluzione
Le regole di confronto possono essere impostate su vari livelli:
- Server
- database
- Colonna
Quindi potresti avere una colonna con distinzione tra maiuscole e minuscole in un database con distinzione tra maiuscole e minuscole. Non ho ancora trovato una situazione in cui un caso aziendale potrebbe essere fatto per la distinzione tra maiuscole e minuscole di una singola colonna di dati, ma suppongo che potrebbe esserci.
Verifica fascicolazione server
SELECT SERVERPROPERTY('COLLATION')
Verifica fascicolazione database
SELECT DATABASEPROPERTYEX('AdventureWorks', 'Collation') SQLCollation;
Verifica regole di confronto colonne
select table_name, column_name, collation_name
from INFORMATION_SCHEMA.COLUMNS
where table_name = @table_name
Altri suggerimenti
Se hai installato SQL Server con le opzioni di confronto predefinite, potresti scoprire che le seguenti query restituiscono gli stessi risultati:
CREATE TABLE mytable
(
mycolumn VARCHAR(10)
)
GO
SET NOCOUNT ON
INSERT mytable VALUES('Case')
GO
SELECT mycolumn FROM mytable WHERE mycolumn='Case'
SELECT mycolumn FROM mytable WHERE mycolumn='caSE'
SELECT mycolumn FROM mytable WHERE mycolumn='case'
Puoi modificare la tua query forzando le regole di confronto a livello di colonna:
SELECT myColumn FROM myTable
WHERE myColumn COLLATE Latin1_General_CS_AS = 'caSE'
SELECT myColumn FROM myTable
WHERE myColumn COLLATE Latin1_General_CS_AS = 'case'
SELECT myColumn FROM myTable
WHERE myColumn COLLATE Latin1_General_CS_AS = 'Case'
-- if myColumn has an index, you will likely benefit by adding
-- AND myColumn = 'case'
SELECT DATABASEPROPERTYEX('<database name>', 'Collation')
Poiché la modifica di questa impostazione può influire sulle applicazioni e sulle query SQL, isolerei prima questo test. Da SQL Server 2000, è possibile eseguire facilmente un'istruzione ALTER TABLE per modificare il criterio di ordinamento di una colonna specifica, imponendo la distinzione tra maiuscole e minuscole. Innanzitutto, esegui la query seguente per determinare a cosa devi ripristinarla:
EXEC sp_help 'mytable'
Il secondo recordset dovrebbe contenere le seguenti informazioni, in uno scenario predefinito:
Collation Nome colonna
mycolumn SQL_Latin1_General_CP1_CI_AS
Qualunque sia la colonna "Fascicolazione", ora sai di cosa hai bisogno per cambiarla dopo aver apportato la seguente modifica, che imporrà la distinzione tra maiuscole e minuscole:
ALTER TABLE mytable
ALTER COLUMN mycolumn VARCHAR(10)
COLLATE Latin1_General_CS_AS
GO
SELECT mycolumn FROM mytable WHERE mycolumn='Case'
SELECT mycolumn FROM mytable WHERE mycolumn='caSE'
SELECT mycolumn FROM mytable WHERE mycolumn='case'
Se questo rovina tutto, puoi cambiarlo semplicemente emettendo una nuova istruzione ALTER TABLE (assicurati di sostituire il mio identificativo COLLATE con quello che hai trovato in precedenza):
ALTER TABLE mytable
ALTER COLUMN mycolumn VARCHAR(10)
COLLATE SQL_Latin1_General_CP1_CI_AS
Se sei bloccato con SQL Server 7.0, puoi provare questa soluzione alternativa, che potrebbe essere un po 'più di un successo sulle prestazioni (dovresti ottenere solo un risultato per la PRIMA corrispondenza):
SELECT mycolumn FROM mytable WHERE
mycolumn = 'case' AND
CAST(mycolumn AS VARBINARY(10)) = CAST('Case' AS VARBINARY(10))
SELECT mycolumn FROM mytable WHERE
mycolumn = 'case' AND
CAST(mycolumn AS VARBINARY(10)) = CAST('caSE' AS VARBINARY(10))
SELECT mycolumn FROM mytable WHERE
mycolumn = 'case' AND
CAST(mycolumn AS VARBINARY(10)) = CAST('case' AS VARBINARY(10))
-- if myColumn has an index, you will likely benefit by adding
-- AND myColumn = 'case'
Il server SQL determina la distinzione tra maiuscole e minuscole di COLLATION
.
WHERE
può essere impostato su vari livelli.
- Server di livello
- a livello di database
- Colonna a livello
- Espressione di livello
È possibile controllare <=> ad ogni livello come menzionato in la risposta di Raj More .
Verifica fascicolazione server
SELECT SERVERPROPERTY('COLLATION')
Verifica fascicolazione database
SELECT DATABASEPROPERTYEX('AdventureWorks', 'Collation') SQLCollation;
Verifica regole di confronto colonne
select table_name, column_name, collation_name
from INFORMATION_SCHEMA.COLUMNS
where table_name = @table_name
Verifica confronto espressioni
Per livello di espressione <=> devi guardare l'espressione. :)
Sarebbe generalmente alla fine dell'espressione come nell'esempio seguente.
SELECT name FROM customer ORDER BY name COLLATE Latin1_General_CS_AI;
Descrizione del fascicolo
Per ottenere la descrizione di ciascun <=> valore provare questo
SELECT * FROM fn_helpcollations()
E dovresti vedere qualcosa del genere.
Puoi sempre mettere una clausola <=> per filtrare e vedere la descrizione solo per il tuo <=>.
Puoi trovare un elenco di regole di confronto qui .
Sei interessato alla raccolta. Puoi creare qualcosa basato su questo frammento:
SELECT DATABASEPROPERTYEX('master', 'Collation');
Aggiorna
Basato sulla tua modifica & # 8212; Se @test
e @TEST
possono mai fare riferimento a due diverse variabili, non è SQL Server. Se vedi problemi in cui la stessa variabile non è uguale a se stessa, controlla se quella variabile è NULL
, perché NULL = NULL
restituisce `false.
Il modo migliore di lavorare con le tabelle già create è che, Vai a SQL Server Query Editor
Tipo: sp_help <tablename>
Questo mostrerà la struttura della tabella, vedere i dettagli per il campo desiderato nella colonna COLLATE.
quindi digitare la query come:
SELECT myColumn FROM myTable
WHERE myColumn COLLATE SQL_Latin1_General_CP1_CI_AS = 'Case'
Potrebbe essere uno schema di caratteri diverso < SQL_Latin1_General_CP1_CI_AS
> ;, quindi meglio scoprire lo schema esatto che è stato usato contro quella colonna.
Come posso verificare se un database in SQL Server fa distinzione tra maiuscole e minuscole?
È possibile utilizzare la query seguente che restituisce il database informato con distinzione tra maiuscole e minuscole o è in ordine binario (con risultato nullo):
;WITH collations AS (
SELECT
name,
CASE
WHEN description like '%case-insensitive%' THEN 0
WHEN description like '%case-sensitive%' THEN 1
END isCaseSensitive
FROM
sys.fn_helpcollations()
)
SELECT *
FROM collations
WHERE name = CONVERT(varchar, DATABASEPROPERTYEX('yourDatabaseName','collation'));
Ulteriori informazioni queste informazioni MSDN ;).
SQL Server non fa distinzione tra maiuscole e minuscole. SELECT * FROM SomeTable
è uguale a SeLeCT * frOM soMetaBLe
.