2012-02-23 17 views
2

私はOracle 11からMS SQL 2008にColdFusionプロジェクトを変換しています。私はトリガ、プロシージャ、および関数を含むDBを変換するためにSSMAを使用しました。配列はIDENTITY列にマッピングされました。MS SQL 2008で生成されたIDを取得します

私はテーブルにINSERT後のデータの履歴を保持するために、別のテーブルに挿入されたデータの一部を書き込む、定義されたトリガを持っているので、これはエラーをスロー

INSERT INTO mytable (col1, col2) 
OUTPUT INSERTED.my_id 
values('val1', 'val2') 

のようにINSERT-ステートメントを使用して、計画

Microsoftは書いている:

OUTPUT句もINTO キーワードを指定せずに指定されている場合は、DML操作の対象は、任意の与えられたDML操作のためにそれに定義された トリガーを有効にすることはできません。たとえば、 OUTPUT句がUPDATE文で定義されている場合、ターゲット表 には有効なUPDATEトリガーを使用できません。 http://msdn.microsoft.com/en-us/library/ms177564.aspx

私は今、最初に生成されたIDと第二に、「バックアップ」の2番目のテーブルに挿入されたデータを取得FOのベストプラクティスは何か思ったんだけど。

これはINSERTに適したアプローチですか?これはINSERTED値が単純に返されるのではなく、一時変数に書き込まれるために機能します。私のテストでは、Microsoftが説明しているように、トリガーに関するエラーを投げずに動作します。

<cfquery> 
DECLARE @tab table(id int); 
INSERT INTO mytable (col1, col2) 
OUTPUT INSERTED.my_id INTO @tab 
values('val1', 'val2'); 
SELECT id FROM @tab; 
</cfquery> 

OUTPUT句を使用する必要がありますか? 1つのcfqueryブロックに複数の句を記述する必要がある場合は、SELECT SCOPE_DENTITY()をよく使うべきではありませんか?

おかげで、最高の、 ベルンハルトは

+0

挿入後に '@ tab'で何をする必要がありますか? 'ID'をCFに返すだけですか? 'OUTPUT'ではなく' SCOPE_IDENTITY() 'を使ってみましたか? Ad Hoc SQLを 'cfquery'に詰め込む代わりに、ストアドプロシージャを使って同じことをやってみましたか? –

+0

生成されたIDを返す以外には@tabを使用しません。 1つのCFQUERYブロックに多くのステートメントを記述することはあまりありません。 'SCOPE_IDENTITY'を使うと、' DECLARE'と 'OUTPUT'は必要なくなります。私が手続きをしていれば、トリガーを無効にせずに、生成されたIDを再度検索しなければなりませんでした。したがって、私は 'SELECT SCOPE_DENTITY()'を想定しています。 –

+0

@Bardware - 私の最初の質問は、cfqueryの['result'](http://help.adobe.com/en_US/ColdFusion/9.0/CFMLRef/WSc3ff6d0ea77859461172e0811cbec22c24-7fae.html)属性と' result。代わりにIDENTITYCOL'変数を使用しますか?最後に内部でSCOPE_IDENTITYを使用します。 – Leigh

答えて

1

これは動作するようです - 行は、トリガー後に干渉しない代わりに、トリガーの結果を返し、挿入、およびテーブルにトリガログインした後、予想通ります:

CREATE TABLE dbo.x1(ID INT IDENTITY(1,1), x SYSNAME); 

CREATE TABLE dbo.log_after(ID INT, x SYSNAME, 
    dt DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP); 
GO 

CREATE TRIGGER dbo.x1_after 
ON dbo.x1 
AFTER INSERT 
AS 
BEGIN 
    SET NOCOUNT ON; 

    INSERT dbo.log_after(x) SELECT x FROM inserted; 
END 
GO 

CREATE TRIGGER dbo.x1_before 
ON dbo.x1 
INSTEAD OF INSERT 
AS 
BEGIN 
    SET NOCOUNT ON; 

    DECLARE @tab TABLE(id INT); 

    INSERT dbo.x1(x) 
     OUTPUT inserted.ID INTO @tab 
     SELECT x FROM inserted; 

    SELECT id FROM @tab; 
END 
GO 

これをcfqueryに書き込むと、出力が返されます。私はCFに精通していないので、結果セットを返すことを知るためにはselectのようなものを見なければならないのかどうか分かりません(ただし、Management Studioで試してみてください) :

INSERT dbo.x1(x) SELECT N'foo'; 

これで、挿入後ロジックをこのトリガーにも移動する必要があります。

今のところ、複数の行が返されることに注意してください(SCOPE_IDENTITY()から得られる単一の結果とは少し異なります)。これはいいことですが、私はそれを指摘したいだけでした。

2

私はこれは、あなたが何をしたいと思う:私はそれは私が誰かは単に使用するのではなく、そのような統合されたアプローチを使用して見てきた最初の時間です認めざるを得ない

<cfquery name="qryInsert" datasource="db" RESULT="qryResults"> 
    INSERT INTO mytable (col1, col2) 
</cfquery> 

<cfset id = qryResults.IDENTITYCOL> 
+0

[cfquery](http://help.adobe.com/en_US/ColdFusion/9.0/CFMLRef/WSc3ff6d0ea77859461172e0811cbec22c24-7fae.html)は、アイデンティティ値の自動取得をサポートしています。 – Leigh

+0

'INSERT'が常に1つの行になることが保証されている場合は、この方がはっきりと好きです。 'INSERT INTO mytable SELECT 1,2 UNION ALL SELECT 2,3;'ならば? –

+0

'OUTPUT'節は、その場合には複数のレコードセットを返すでしょう。 –

0

を内蔵のPK検索別のデータベース要求(example)に分割します。

+1

リンクは時間がたつにつれて破損する可能性があるので、コードスニペットまたは2つを含むようにあなたの投稿を更新することができます。 – Leigh

関連する問題