2011-01-11 5 views
2

私はタスクを持っていました - 実際のテーブルデータの変更(同じ値の更新だけでなく)で動作する更新トリガを作成するタスクがありました。その目的のために私はコピーテーブルを作成し、更新された行を古いコピーされた行と比較し始めました。トリガが完了すると、それはコピーを実現するためにneccessaryです:ストアドプロシージャとトリガー

UPDATE CopyTable SET 
    id = s.id, 
    -- many, many fields 
FROM MainTable s WHERE s.id IN (SELECT [id] FROM INSERTED) 
       AND CopyTable.id = s.id; 

私はもうトリガーにこの醜いコードを持って好きではないので、私は、ストアドプロシージャにそれを抽出しています

CREATE PROCEDURE UpdateCopy AS 
BEGIN 
UPDATE CopyTable SET 
    id = s.id, 
    -- many, many fields 
    FROM MainTable s WHERE s.id IN (SELECT [id] FROM INSERTED) 
    AND CopyTable.id = s.id; 
END 

結果は次のとおりです。 - 無効なオブジェクト名 'INSERTED'。これを回避するにはどうすればよいですか?

よろしく、

+1

あなたは単にトリガー内からストアドプロシージャを呼び出すためにしようとしています。また、同様の手順他の場所を呼ぶ可能性がありますか? – Sparky

+0

いいえ、トリガーからのみです。 – noober

答えて

2

問題は、挿入されたが、トリガ時にのみ利用可能であるということである

- 呼び出すためのトリガーの変更 - IDの

DECLARE @idStack VARCHAR(max) 
SET @idStack=',' 
SELECT @[email protected]+ltrim(str(id))+',' FROM INSERTED 

のリストを構築するためのトリガの変更ストアドプロシージャ

から

CREATE PROCEDURE UpdateCopy(@IDLIST VARCHAR(max)) AS 
BEGIN 
UPDATE CopyTable SET 
    id = s.id, 
    -- many, many fields 

    FROM MainTable s WHERE charindex(','+ltrim(str(s.id))+',',@idList) > 0 
    AND CopyTable.id = s.id; 
END 

パフォーマンスは素晴らしいことではないだろうが、それはあなたがやりたいことを許可しなければならないIDのカンマ区切りのリストを取るために手順。

ちょうどその場でで入力されたが、トリガー内のコードを残すOK

+0

素敵なハック!ありがとうございました。しかし、トリガーをスピードアップしようとすると、それは選択肢ではありません。 (トリガーはSQLCLRなので、コピーSQLスクリプトは毎回新しいクエリとしてADO.Netを介して呼び出されているので、サーバーにスクリプトをキャッシュする機会を与えるストアドプロシージャを作成する方が良いでしょう)。 – noober

4

を実行する必要があります。 INSERTEDは、トリガコードでのみ使用可能な疑似テーブルです。 この疑似テーブルの値を渡そうとすると、非常に多くのエントリが含まれている可能性があります。

これは、宣言型データアクセス言語であるT-SQLです。それはあなたの常用の手続き型プログラミング言語ではありません。 「コード再利用」のような一般的な知恵はSQLでは適用されず、パフォーマンスの問題のみが発生します。それが属するトリガーにコードを残します。再ファクタリングを容易にするために、いくつかのコード生成ツールを使用してトリガを生成するので、トリガを簡単にリファクタリングすることができます。

+0

私はRemusに同意します。私のコードは動作しますが、Work-aroundだけです。あなたがそれをやらなければならない唯一の理由なら、あなたはトリガの中で醜いコードが好きではないということです。あなたが何か他の理由があるなら、私が書いたものはあなたがそれを回避することを可能にします.... – Sparky

+0

OK。実際には、SQLCLRトリガであり、プロシージャを作成する理由は、呼び出しごとに毎回同じ巨大なテキストをSQLサーバーに送信するため、パフォーマンスを向上させようとしていました。 – noober

+0

なぜあなたのトリガーはSQLCLRトリガーですか?おそらく、あなたがしようとしていることについてもっと説明する必要があります。トリガでCLRを使用することは決して考えません。通常のSQLよりも処理速度が遅いためです。 – HLGEM

関連する問題