2016-12-02 19 views
0

挿入されたテーブルをトリガで動的に変更しようとしています。 NOT NULL制約を動的に作成する必要があります。 Fieldsテーブルを照会してNOT NULLフィールドを取得します。次に、NOT NULLフィールドに基づいてALTER DDLクエリを作成します。 ALTER文を実行すると、このエラーが表示されます。挿入されたテーブルをトリガで動的に変更する方法

は、それが存在しないか、またはあなたが ここ権限

を持っていないので、「挿入」オブジェクトを見つけることができません私が働いているコードです:

ALTER TRIGGER [dbo].[tr_INSERT_UPDATE_Data1] 
ON [dbo].[Data1] 
AFTER INSERT, UPDATE 
as 

DECLARE @ObjectId INT 
DECLARE @AlterQueryStr NVARCHAR(MAX) 

SELECT TOP 1 @ObjectId = object_id FROM inserted 

SELECT FieldNumber 
INTO #NotNullFieldNumbers 
FROM dbo.Fields 
WHERE ObjectId = @ObjectId AND NotNull = 1 

IF EXISTS(SELECT * FROM #NotNullFieldNumbers) 
BEGIN 
    DECLARE @AlterTableTemp NVARCHAR(MAX) 

    SELECT @AlterTableTemp = STUFF((SELECT ';' + 'ALTER TABLE inserted ALTER COLUMN Field' + cast([FieldNumber] as VARCHAR(100)) + ' VARCHAR(MAX) NOT NULL' 
       FROM #NotNullFieldNumbers 
       FOR 
       XML PATH('') 
      ), 1, 1, '') 

    EXEC sp_executesql @AlterTableTemp 

END 
+2

なぜあなたは挿入されたテーブルを変更したいですか?それはsqlがテーブルに挿入または更新された新しい値を保持する特別なテーブル変数のように考えてください。これを変更してもDML操作は変更されず、その表のデータを変更してもDML操作が実行されていた表は変更されません。また、NULLに設定すると、NOT NULLに設定すると、許可されていればエラーになります。実際の質問のように思えます(挿入された値がヌルでないことを確認してください)..... – Matt

+5

データベーススキーマを**変更しても大したことはないようですトリガー.......あなたのアプローチを再考する必要があります、これはこれらの要件に対処するための良い方法ではありません! –

+3

これは本当に恐ろしい**のアイデアです。あなたはそれで解決しようとしている_actual_問題は何ですか?なぜあなたはテーブルのNOT NULL属性を動的に変更する必要がありますか? Plus: 'inserted'" table "(変数)は、トリガーの実行時にのみ存在します。だから、それを修正することに意味はない。 –

答えて

1

はさておきDD33をinsertedで動的に操作する理由はなぜですか?質問は、inserteddeletedテーブルはトリガーのコード内でしかアクセスできないため動作しません。動的SQLは、それが呼び出されたコンテキストではなく、独自の実行コンテキストで実行されるため、object not foundエラーが発生します。

編集:

この質問と仮定すると同様のトピックに関するごotherrecent質問に関し、ここでは3つのField...列を持つData1テーブルにトリガを使用してこの問題にアプローチする一つの方法です(この例ではに拡張可能ですより多くの列で作業します)。

トリガーは、次に、ObjectIdごとに1つの列にFieldsテーブルをINGのinsertedテーブルにこれを接合し、関連Fields.NotNull値が挿入FieldNの値を比較することによって動作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)