2009-05-14 4 views
1

SQL Serverの "insert into"トリガの代わりに、単一の列(PromoCode)を挿入するSQL Serverがあります。それはすべて完璧に動作しますが、私は、私は、実際のINSERT文で列をハードコーディングしなければならなかったという事実が好きではありません:SQL Serverトリガーで値を変更するときハードコーディングを避ける

CREATE TRIGGER PopulateOrderPromoCode ON Order 
INSTEAD OF INSERT 
AS BEGIN 
    --// Get the Promo Code 
    DECLARE @PromoCode int; 
    EXEC GetPromoCode @PromoCode OUTPUT;  

    --// Insert the order with the new Promo Code 
    INSERT INTO Order (Id, CustomerId, PromoCode) 
     SELECT Id, CustomerId, @PromoCode FROM inserted; 
END 

を私は単に@PromoCodeでinserted.PromoCode内の値を交換して、可能性を好むだろう使用:

INSERT INTO Order 
    SELECT * FROM inserted; 

これを行うことはできますか?

+1

一度に1つの行しか挿入しないことは確実ですか?誰か(ある一晩後にテーブルを修正するDBA)が1つのステートメントに複数の行を挿入すると、挿入されたすべての行に同じ@PromoCode値が割り当てられます。 –

+0

バルクコピーの誰ですか? – NotMe

答えて

0

INSERTEDは、任意のトリガーでアクセスできる読み取り専用の一時テーブルです。それを変更することはできません。

そして、あなたがINSERTを実行するために使用している方法が最良の方法です。だから、何も問題はない。 INSERTを実行している間に列を指定すると良いです(私によると)。

+0

Trueですが、現時点では、列がOrderテーブルに追加されたときにトリガーを更新する必要があります。理想的には、トリガーは、Order.PromoCode列にのみ作用するので透過的であり、他のOrder列には関与してはいけません。 – user97280

-2

唯一の選択肢は、動的SQLです。これを試してください:

CREATE TRIGGER PopulateOrderPromoCode 
ON Order 
INSTEAD OF INSERT 
AS 
BEGIN  
    --// Get the Promo Code  
    DECLARE @PromoCode int;   
    EXEC GetPromoCode @PromoCode OUTPUT;  

    DECLARE @InsertSQL nvarchar(2000), @SelectSQL nvarchar(2000) 
    SET @InsertSQL = 'INSERT INTO Order (' 
    SET @SelectSQL = 'SELECT ' 

    DECLARE @CurrentCol sysname 
    SET @CurrentCol = '' 



    WHILE EXISTS ( SELECT TOP 1 QUOTENAME(name) 
        FROM sys.syscolumns 
        WHERE object_name(id) = 'Order' 
        AND  name <> 'PromoCode' 
        AND  name > @CurrentCol) 
    BEGIN 
     SET @CurrentCol = (SELECT TOP 1 QUOTENAME(name) 
          FROM sys.syscolumns 
          WHERE object_name(id) = 'Order' 
          AND  name <> 'PromoCode' 
          AND  QUOTENAME(name) > @CurrentCol 
          ORDER BY name) 
     IF @CurrentCol IS NULL Break; 

     SET @InsertSQL = @InsertSQL + @CurrentCol + ', ' 
     SET @SelectSQL = @SelectSQL + @CurrentCol + ', ' 
    END 

    --Finish and concatenate the strings 
    SET @InsertSQL = @InsertSQL + 'PromoCode) ' 
    SET @SelectSQL = @SelectSQL + '''' + @PromoCode + '''' + ' FROM INSERTED' 

    DECLARE @MasterSQL nvarchar(2000) 
    SET @MasterSQL = @InsertSQL + @SelectSQL 

    EXEC (@MasterSQL) 
END 

BTW - "order"はSQLの予約語です。 OrdersまたはOrderHeaderを試してみてください。

2

INSTEAD OF INSERTトリガー(インサート・ロジックを引き継ぐために持っている)

(あなたが挿入に加えてのものを行うことができます)通常のINSERTトリガ

を使用し、使用しないでください

これは、プロモーションコードなしで(nullを許可する)、またはプロモーションコードが何かにデフォルト設定されていることを前提としています。

CREATE TRIGGER PopulateOrderPromoCode ON Order 
FOR INSERT 
AS 
BEGIN 
    --// Get the Promo Code 
    DECLARE @PromoCode int;  
    EXEC GetPromoCode @PromoCode OUTPUT;   

    --// update the order with the new Promo Code 
    UPDATE Order SET PromoCode = @PromoCode 
     WHERE ID IN (SELECT ID FROM inserted) 
END 
関連する問題