はさておきDD33をinserted
で動的に操作する理由はなぜですか?質問は、inserted
とdeleted
テーブルはトリガーのコード内でしかアクセスできないため動作しません。動的SQLは、それが呼び出されたコンテキストではなく、独自の実行コンテキストで実行されるため、object not found
エラーが発生します。
編集:
この質問と仮定すると同様のトピックに関するごotherrecent質問に関し、ここでは3つのField...
列を持つData1
テーブルにトリガを使用してこの問題にアプローチする一つの方法です(この例ではに拡張可能ですより多くの列で作業します)。
トリガーは、次に、ObjectId
ごとに1つの列にFields
テーブルをINGのinserted
テーブルにこれを接合し、関連Fields.NotNull
値が挿入Field
Nの値を比較することによって動作PIVOT
。このコードでは、NotNull
の値を文字列に変換して理解しやすくしていますが、bit
の値を使用することもできます。
このコードでは、同じバッチ内での値が2つ以上あるINSERT
またはUPDATE
をサポートします。
--create schema
CREATE TABLE fields (ObjectId int , FieldNumber int , NotNull bit)
INSERT fields (ObjectId, FieldNumber, NotNull)
VALUES
(100,1,1),(100,2,1),(100,3,0),
(200,1,1),(200,2,1),(200,3,1)
CREATE TABLE Data1 (ObjectId int , Field1 int ,Field2 int ,Field3 int)
GO
CREATE TRIGGER [dbo].[tr_INSERT_UPDATE_Data1]
ON [dbo].[Data1]
AFTER INSERT, UPDATE
AS
IF EXISTS (SELECT *
FROM inserted AS i
JOIN ( SELECT ObjectId, Field1,Field2,Field3
FROM (
SELECT ObjectId, CONCAT('Field',FieldNumber) AS colName,
CASE WHEN NotNull = 1 THEN 'NOT NULL' ELSE 'NULL' END AS NotNull
FROM fields
) AS s
PIVOT
(
MAX(NotNull)
FOR colName IN (Field1,Field2,Field3)
) AS p
) AS f
ON f.ObjectId = i.ObjectId
WHERE (f.Field1 = 'NOT NULL' AND i.Field1 IS NULL)
OR (f.Field2 = 'NOT NULL' AND i.Field2 IS NULL)
OR (f.Field3 = 'NOT NULL' AND i.Field3 IS NULL)
)
THROW 50001, 'Cannot insert NULL into a field marked NOT NULL',1
GO
--Tests
--1 insert good data
INSERT Data1 (ObjectId, Field1,Field2,Field3)
VALUES (100,1,2,3)
--2 NULL blocked for ObjectId 100, Field1 NULL
INSERT Data1 (ObjectId, Field1,Field2,Field3)
VALUES (100,NULL,2,3)
--3 NULL blocked for ObjectId 100, Field2 NULL
INSERT Data1 (ObjectId, Field1,Field2,Field3)
VALUES (100,1,NULL,3)
--4 insert good data (Field3 NULL permitted)
INSERT Data1 (ObjectId, Field1,Field2,Field3)
VALUES (100,1,2,NULL)
--4 multiple ObjectIds supported - NULL blocked for all ObjectId 200 fields
INSERT Data1 (ObjectId, Field1,Field2,Field3)
VALUES (100,1,2,3),
(200,NULL,NULL,NULL)
なぜあなたは挿入されたテーブルを変更したいですか?それはsqlがテーブルに挿入または更新された新しい値を保持する特別なテーブル変数のように考えてください。これを変更してもDML操作は変更されず、その表のデータを変更してもDML操作が実行されていた表は変更されません。また、NULLに設定すると、NOT NULLに設定すると、許可されていればエラーになります。実際の質問のように思えます(挿入された値がヌルでないことを確認してください)..... – Matt
データベーススキーマを**変更しても大したことはないようですトリガー.......あなたのアプローチを再考する必要があります、これはこれらの要件に対処するための良い方法ではありません! –
これは本当に恐ろしい**のアイデアです。あなたはそれで解決しようとしている_actual_問題は何ですか?なぜあなたはテーブルのNOT NULL属性を動的に変更する必要がありますか? Plus: 'inserted'" table "(変数)は、トリガーの実行時にのみ存在します。だから、それを修正することに意味はない。 –