Problema:
Causa:a coluna 'Nome' não diferencia maiúsculas de minúsculas (
CI
) colação. Solução:Você tem que usar um
CS
collation:SELECT * FROM fn_helpcollations() WHERE description LIKE N'%case-sensitive%'
. Observação:há um agrupamento de banco de dados e um agrupamento em nível de coluna. E, há, também, um agrupamento de nível de servidor.
SELECT DATABASEPROPERTYEX(DB_NAME(), 'Collation') AS DatabaseCollation
/*
-- Sample output (my database)
DatabaseCollation
----------------------------
SQL_Latin1_General_CP1_CI_AS
*/
SELECT col.collation_name AS ColumnCollation
FROM sys.columns col
WHERE col.object_id = OBJECT_ID(N'dbo.Table_2')
AND col.name = N'Name'
/*
-- Sample output (my database)
ColumnCollation
----------------------------
SQL_Latin1_General_CP1_CI_AS
*/
Simplesmente alterar o agrupamento do banco de dados NÃO altere o agrupamento para tabelas e colunas de usuários existentes:
Fonte
Após alterar o agrupamento do banco de dados , a saída das consultas acima será:
/*
DatabaseCollation -- changed
----------------------------
SQL_Latin1_General_CP1_CS_AS
*/
/*
ColumnCollation -- no change
----------------------------
SQL_Latin1_General_CP1_CI_AS
*/
e, como você pode ver, o agrupamento da coluna
Name
permanece CI. Além disso, alterar o agrupamento do banco de dados afetará apenas as novas tabelas e colunas criadas. Assim, alterar o agrupamento do banco de dados pode gerar resultados estranhos (na minha opinião ) porque alguns
[N][VAR]CHAR
colunas serão CI e as novas colunas serão CS. Solução detalhada nº 1:se apenas algumas consultas para a coluna
Name
precisa ser CS
então vou reescrever WHERE
cláusula dessas consultas assim:SELECT Name
FROM dbo.Table_2
WHERE Name LIKE 'Joe' AND Name LIKE 'Joe' COLLATE SQL_Latin1_General_CP1_CS_AS
Isso dará uma alteração no SQL Server para fazer um
Index Seek
na coluna Name
(há um índice na coluna Name
). Além disso, o plano de execução incluirá uma conversão implícita (consulte Predicate
propriedade para Index Seek
) devido ao seguinte predicado Name = N'Joe' COLLATE SQL_Latin1_General_CP1_CS_AS
. Solução detalhada nº 2:se todas as consultas para a coluna
Name
precisa ser CS, então vou alterar o agrupamento apenas para a coluna Name
portanto:-- Drop all objects that depends on this column (ex. indexes, constraints, defaults)
DROP INDEX IX_Table_2_Name ON dbo.Table_2
-- Change column's collation
ALTER TABLE dbo.Table_2
ALTER COLUMN Name VARCHAR(50) COLLATE SQL_Latin1_General_CP1_CS_AS
-- Replace VARCHAR(50) with proper data type and max. length
-- Replace COLLATE SQL_Latin1_General_CP1_CS_AS with the right CS collation
-- Recreate all objects that depends on column Name (ex. indexes, constraints, defaults)
CREATE INDEX IX_Table_2_Name ON dbo.Table_2 (Name)
-- Test query
SELECT Name
FROM dbo.Table_2
WHERE Name LIKE 'Joe'