テーブルでデータ検証を実行しようとしていますが、複数の行と列をチェックする必要があります。基本的に、特定のツールについて、アクティブ バージョンまたはベータ バージョンとしてフラグが付けられたバージョンが少なくとも 1 つ存在することを確認したいと考えています。
これを確認する唯一の方法は、ユーザー定義のスカラー関数とCHECK
、関数を呼び出す制約を使用することです。期待どおりの結果を返す関数を作成できました (OK の場合は 0、そうでない場合は1 ) INSERT
。UPDATE
orステートメントを実行するDELETE
と、チェック制約は失敗しないため、どちらの場合も不正なデータになる可能性があります。
これは、私が使用しているテーブルと関数のサンプルです。
CREATE TABLE VersionTest(VersionID int NOT NULL, ToolID int NOT NULL, IsActiveVersion bit NOT NULL, IsBetaVersion bit NOT NULL)
GO
ALTER TABLE VersionTest ADD CONSTRAINT [DF_VersionTest_IsActiveVersion] DEFAULT ((0)) FOR [IsActiveVersion]
GO
ALTER TABLE VersionTest ADD CONSTRAINT [DF_VersionTest_IsBetaVersion] DEFAULT ((0)) FOR [IsBetaVersion]
GO
CREATE FUNCTION fn_ValidateVersionTest(@toolID int) RETURNS SMALLINT
AS
BEGIN
IF (@toolID = -1)
BEGIN
RETURN 0
END
ELSE
BEGIN
IF EXISTS (SELECT 1
FROM VersionTest
WHERE ToolID = @toolID
GROUP BY ToolID, IsActiveVersion, IsBetaVersion
HAVING (SUM(CASE WHEN IsActiveVersion = 1 THEN 1 ELSE 0 END) +
SUM(CASE WHEN IsBetaVersion = 1 THEN 1 ELSE 0 END)) > 0)
RETURN 0
END
RETURN 1
END
GO
ALTER TABLE VersionTest WITH CHECK ADD CONSTRAINT [CK_VersionTest] CHECK (([dbo].[fn_ValidateVersionTest]([ToolID])=(0)))
GO
ALTER TABLE VersionTest CHECK CONSTRAINT [CK_VersionTest]
GO
次の INSERT ステートメントは正常に機能します。
INSERT INTO VersionTest (ToolID, VersionID, IsActiveVersion, IsBetaVersion)
VALUES (1, 1, 1, 0)
INSERT INTO VersionTest (ToolID, VersionID, IsActiveVersion, IsBetaVersion)
VALUES (1, 2, 0, 0)
予想どおり、この INSERT ステートメントは失敗します。
INSERT INTO VersionTest (ToolID, VersionID, IsActiveVersion, IsBetaVersion)
VALUES (2, 1, 0, 0)
ただし、次の UPDATE および DELETE ステートメントは、期待どおりに失敗していません。
UPDATE VersionTest
SET IsActiveVersion = 0, IsBetaVersion = 0
WHERE VersionID = 1
DELETE VersionTest WHERE VersionID = 1
これを行うべき別の方法はありますか?代わりにトリガーを使用する必要がありますか?