web-dev-qa-db-ja.com

SQL ServerのトリガーでINSERTの値を編集するにはどうすればよいですか?

テーブルTbがあります

ID | Name   | Desc
-------------------------
 1 | Sample | sample desc

INSERTのトリガーを作成して、挿入するDescの値を変更します。次に例を示します。

INSERT INTO Tb(Name, Desc) VALUES ('x', 'y')

結果として

ID | Name   | Desc
-------------------------
 1 | Sample | sample desc
 2 | x      | Y edited

上記の例では、挿入するDescの値を取得し、大文字に変更して、最後にeditedを追加しました。

それが私が必要とするもので、挿入されているDescを取得して修正します。

どうやってやるの?

更新後に挿入後に処理する方が良いですか?または、INSTEAD OF INSERTでトリガーを作成し、テーブル構造が変更されるたびにトリガーを変更しますか?

29
BrunoLM

挿入後トリガーを使用します。 inserted疑似テーブルから、主キーのTbに結合します。次に、descの値を更新します。次のようなもの:(ただし、コンパイルできない場合があります)

CREATE TRIGGER TbFixTb_Trg 
ON  Tb  
AFTER INSERT 
AS  
BEGIN 
    UPDATE Tb
    SET DESC = SomeTransformationOf(i.DESC)
    FROM Tb
    INNER JOIN inserted i on i.Id = Tb.Id
END  
GO

このトリガーは、挿入が発生した後、insertステートメントが完了する前に発生します。そのため、新しい誤った値はすでにターゲットテーブルに配置されています。このトリガーは、列の追加、削除などに応じて変更する必要はありません。

警告整合性制約は、afterトリガーが起動する前に実施されます。したがって、適切な形式のDESCを実施するためにチェック制約をかけることはできません。トリガーが何かを修正する前にステートメントが失敗するためです。 (それに頼る前にこのパラグラフを再確認してください。トリガーを書いてからしばらく経ちました。)

38

Descの実際の新しい値をどこで取得するかはわかりませんが、別のテーブルなどから取得していると思います。しかし、おそらくあなたはこの方法でそれをしたい理由があるので、以下は私がそれについてどうやって行くかの例です。

必要なものはINSTEAD OF INSERTトリガーと呼ばれ、テーブルに挿入する代わりに起動し、すべてのロジックを与えます。

CREATE TRIGGER trgUpdateDesc
ON  Tb 
INSTEAD OF INSERT
AS 
BEGIN
    SET NOCOUNT ON;
    INSERT INTO Tb (Name, [Desc])
    SELECT Name, [Desc] + 'edited'
    FROM inserted
END 
GO

値を取得する場所がわからないため、Wordを「編集済み」にハードコーディングしましたが、変数または別のテーブルの値に簡単に置き換えることができます。

ああ、また、[]をDescの周りに置いてください。これはSQLサーバーの重要なWordであるため(降順を表す)

お役に立てば幸いです!

編集:

テーブル構造にあまり依存しないようにもう少し堅牢にしたい場合は、AFTER INSERTトリガーを使用してそのようなフィールドを更新するだけで済みます。

CREATE TRIGGER [dbo].[trgUpdateDesc]
   ON  [dbo].[Tb] 
   AFTER INSERT
AS 
BEGIN
    SET NOCOUNT ON;
    UPDATE Tb
    SET [Desc] = UPPER(inserted.[Desc]) +  ' Edited'
    FROM inserted INNER JOIN Tb On inserted.id = Tb.id
END 
26
JonVD

一時テーブルはINSTEAD OF INSERT関係のないすべてのテーブル列を明示的にリストすることを避けながらトリガーします。

CREATE TRIGGER trgUpdateDesc
    ON Tb 
    INSTEAD OF INSERT
AS 
BEGIN
    SET NOCOUNT ON;
    select * into #tmp from inserted;
    UPDATE #tmp SET Desc = Desc + 'edited' --where ...;
    insert into Tb select * from #tmp;
    drop table #tmp;
END 

テーブルに新しい列を追加するときに、このコードを修正する必要はありません。

ただし、 一時テーブルの追加オーバーヘッド に注意してください。

また、SQL ServerトリガーはバルクDML操作に対して1回起動し、 複数行の挿入を正しく処理する でなければならないことに注意してください。

9
Vadzim

INSTEAD OFトリガー。

CREATE TRIGGER Tb_InsteadTrigger on Tb
INSTEAD OF INSERT
AS
BEGIN
...

これにより、テーブルに入る前にデータを操作できます。トリガーは、データをテーブルに挿入する役割を果たします。

4
bobs