次の方法で共有


CHECKSUM (Transact-SQL)

適用対象: SQL Server Azure SQL データベース Azure SQL Managed Instance Azure Synapse Analytics Microsoft Fabric の SQL 分析エンドポイント Microsoft Fabric のウェアハウス

CHECKSUM 関数は、テーブルの行または式のリストで計算されたチェックサム値を返します。 CHECKSUM を使用して、ハッシュ インデックスを作成します。

Transact-SQL 構文表記規則

構文

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 が返されます。そのため、文字列にハッシュ文字を追加しても、チェックサム リストにデータを追加しても何の変化もありません。 実際の問題:

  1. チェックサムでは、数値文字列の負のシグネチャが無視されます
SELECT CHECKSUM(N'1'), CHECKSUM(N'-1');
  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)