sql >> データベース >  >> RDS >> Sqlserver

SQLServerのようなクエリでは大文字と小文字は区別されません

    問題:

    原因:列'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'
    



    1. codeigniterでテーブルを正しくエイリアスする方法は?

    2. mysqlの列で許可される最大長を決定します

    3. PowerShellを知る必要があるため

    4. MySQLは、過去12か月の数量を月ごとにグループ化して取得します