CHECKSUM (Transact-SQL)
適用対象: SQL Server Azure SQL データベース Azure SQL Managed Instance Azure Synapse Analytics Microsoft Fabric の SQL 分析エンドポイント Microsoft Fabric のウェアハウス
CHECKSUM
関数は、テーブルの行または式のリストで計算されたチェックサム値を返します。 CHECKSUM
を使用して、ハッシュ インデックスを作成します。
構文
CHECKSUM ( * | expression [ ,...n ] )
Note
この構文は、Azure Synapse Analytics のサーバーレス SQL プールでサポートされていません。
引数
*
この引数は、チェックサムの計算がすべてのテーブル列をカバーしていることを指定します。 列のいずれかが比較できないデータ型である場合、CHECKSUM
ではエラーが返されます。 比較できないデータ型は次のとおりです。
- cursor
- image
- ntext
- text
- XML
比較できないデータ型には、これらのデータ型のいずれかを基本データ型とする sql_variant もあります。
式 (expression)
比較できないデータ型を除く、任意のデータ型の式を指定します。
戻り値の型
int
解説
CHECKSUM
では、引数リストに対してハッシュ値 (チェックサム) が計算されます。 このハッシュ値を使用して、ハッシュ インデックスを作成します。 CHECKSUM
関数に列の引数があり、計算された CHECKSUM
値を基にインデックスを作成する場合、結果はハッシュ インデックスになります。 このハッシュ インデックスは、列で等値検索を行うときに使用できます。
CHECKSUM
はハッシュ関数のプロパティとなります。CHECKSUM
を任意の 2 つの式のリストに適用した場合、その 2 つのリストに対応する要素のデータ型が同じで、等号 (=) 演算子により比較した場合にそれらの対応する要素が等しければ、同じ値が返されます。 CHECKSUM
関数の目的のために、指定した型の NULL 値は等しいものとして比較されるように定義されます。 式リストのいずれかの値を変更した場合は、そのリストのチェックサムも変わります。 ただし、これは保証されません。
そのため、値が変更されたかどうかを検出する際には、アプリケーションが変更を検出できないことを許容できる場合のみ、CHECKSUM
の使用をお勧めします。 それ以外の場合は、代わりに HASHBYTES
の使用を検討してください。 MD5 ハッシュ アルゴリズムを指定した場合は、HASHBYTES
から 2 つの異なる入力に対して同じ結果が返される可能性が CHECKSUM
よりもはるかに低くなります。
CHECKSUM
では、nchar と nvarchar のダッシュ文字 (N'-'
または nchar(45)
) が無視されます。 そのため、2 つの文字列の間でダッシュが唯一の違いになる場合、ハッシュが必ず競合します。 別の言い方をすると、Select checksum(nchar(45));
でも Select checksum(N'-');
でも値 0
が返されます。そのため、文字列にハッシュ文字を追加しても、チェックサム リストにデータを追加しても何の変化もありません。
実際の問題:
- チェックサムでは、数値文字列の負のシグネチャが無視されます
SELECT CHECKSUM(N'1'), CHECKSUM(N'-1');
- チェックサム比較では、ストアド プロシージャ定義でコードがコメントアウトされたことを検出できません
CREATE PROCEDURE Checksum_Test AS
BEGIN
RAISERROR('Error Raised',18,1);
RETURN 1;
END
GO
-- get checksum for original proc definition.
SELECT
checksum(definition),
definition
FROM sys.sql_modules
WHERE object_id = object_id('Checksum_Test');
GO
-- comment out a line of code in the proc.
ALTER PROCEDURE Checksum_Test AS
BEGIN
--RAISERROR('Error Raised',18,1);
RETURN 1;
END
GO
-- get checksum for altered proc definition. Note the definition text now includes the -- comment dashes.
SELECT
checksum(definition),
definition
FROM sys.sql_modules
WHERE object_id = object_id('Checksum_Test');
DROP PROCEDURE Checksum_Test
CHECKSUM
では、nchar 文字列と nvarchar 文字列の末尾スペースがトリミングされます。 結果は無視されるダッシュの問題と同じです。
式の順序は、計算される CHECKSUM
値に影響します。 CHECKSUM(*)
で使用される列の順序は、テーブルまたはビュー定義に指定された列の順序です。 これには、計算列が含まれます。
CHECKSUM
値は照合順序によって異なります。 異なる照合順序で保存された同じ値は別の CHECKSUM
値を返します。
CHECKSUM ()
では、結果が一意になるとは限りません。
例
これらの例は、CHECKSUM
を使用してハッシュ インデックスを作成する方法を示しています。
ハッシュ インデックスを作成するために、最初の例では、インデックスを作成するテーブルに計算されたチェックサム列を追加します。 次に、チェックサム列にインデックスを構築します。
-- Create a checksum index.
SET ARITHABORT ON;
USE AdventureWorks2022;
GO
ALTER TABLE Production.Product
ADD cs_Pname AS CHECKSUM(Name);
GO
CREATE INDEX Pname_index ON Production.Product (cs_Pname);
GO
この例では、ハッシュ インデックスとしてチェックサム インデックスを使用することを示しています。 これにより、インデックスを作成する列が長い文字列の場合は、インデックス作成速度を向上させるのに役立ちます。 チェックサム インデックスは、等値検索に使用できます。
/*Use the index in a SELECT query. Add a second search
condition to catch stray cases where checksums match,
but the values are not the same.*/
SELECT *
FROM Production.Product
WHERE CHECKSUM(N'Bearing Ball') = cs_Pname
AND Name = N'Bearing Ball';
GO
計算列にインデックスを作成するとチェックサム列が具体化され、ProductName
値を変更すると、それがどのような変更であってもチェックサム列に反映されます。 代わりに、インデックスを作成する列に直接インデックスを作成することができます。 ただし、長いキー値の場合は、通常のインデックスはチェックサム インデックスと同様に機能しない可能性があります。
関連項目
CHECKSUM_AGG (Transact-SQL)
HASHBYTES (Transact-SQL)
BINARY_CHECKSUM (Transact-SQL)