問題:
原因:列'Name'で大文字と小文字が区別されません(CI
)照合。
解決策:CS
を使用する必要があります 照合:SELECT * FROM fn_helpcollations() WHERE description LIKE N'%case-sensitive%'
。
注:データベース照合と列レベル照合があります。また、サーバーレベルの照合もあります。
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
*/
データベース照合を変更するだけではありません 既存のユーザーテーブルと列の照合を変更します:
データベース照合の変更後 、上記のクエリの出力は次のようになります。
/*
DatabaseCollation -- changed
----------------------------
SQL_Latin1_General_CP1_CS_AS
*/
/*
ColumnCollation -- no change
----------------------------
SQL_Latin1_General_CP1_CI_AS
*/
そして、あなたが見ることができるように、列Name
CIのままです。
さらに、データベース照合を変更すると、新しく作成されたテーブルと列にのみ影響するため、データベース照合を変更すると、奇妙な結果が生成される可能性があります(私の意見では )一部の[N][VAR]CHAR
列はCIになり、新しい列はCSになります。
詳細な解決策#1:列Name
に対するクエリがいくつかある場合 CS
である必要があります 次に、WHERE
を書き直します したがって、これらのクエリの句:
SELECT Name
FROM dbo.Table_2
WHERE Name LIKE 'Joe' AND Name LIKE 'Joe' COLLATE SQL_Latin1_General_CP1_CS_AS
これにより、SQLServerが変更されてIndex Seek
が実行されます。 列Name
(列Name
にインデックスがあります )。また、実行プランには暗黙的な変換が含まれます(Predicate
を参照) Index Seek
のプロパティ )次の述語のためName = N'Joe' COLLATE SQL_Latin1_General_CP1_CS_AS
。
詳細な解決策#2:列Name
に対するすべてのクエリの場合 CSである必要がある場合は、列Name
の照合のみを変更します したがって:
-- 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'