2017-01-12 3 views
0

私はMSSQLサーバーでHibernateを使用して、既存のデータベースと統合されたソフトウェアを作成しています。テーブルに挿入する必要があるinstead of insertトリガがあります。これは、@@Identityを意味します。つまり、Hibernateの意味ですsave挿入された行のIDを取得できません。私はトリガーを制御することはできません(それを変更することはできません)。私はthisの質問を見ましたが、それは私の引き金が持っていない手続きを含んでいます。私は、全体のトリガーを投稿することはできませんが、うまくいけば、私は全体でポイントを取得するのに十分投稿することができます:挿入された行のIDを取得するための信頼できる方法がある場合、私は思っていた挿入トリガーの代わりにIDを取得

CREATE TRIGGER TrigName ON TableName 
INSTEAD OF INSERT 
AS 
SET XACT_ABORT ON 
BEGIN TRANSACTION 
-- several DECLARE, SET statements 
-- a couple of inserts into other tables for business logic 
-- plain T-SQL statements without procedures or functions 
... 

-- this is the actual insert that i need to perform 
-- to be honest, I don't quite understand how INSERTED table 
-- was filled with all necessary columns by this point, but for now 
-- I accept it as is (I am no SQL pro...) 
INSERT INTO ClientTable (<columns>) 
SELECT <same columns> from INSERTED 

-- a couple of UPDATE queries to unrelated tables 
... 

COMMIT TRANSACTION; 

を?私が考えて作成しようとした1つの解決策は、新たに挿入された行をdbに追加した新しいテーブルに書き込む同じテーブルにon insertトリガをインストールすることです。私はそのテーブルをキューとして使用したいと思います。 Hibernateでトランザクションをコミットした後、私はそのテーブルに入り、ちょうど挿入した情報(私はまだ同じメソッドのスコープからアクセスできます)でselectを実行して、IDを取得して最後にその行を削除できます。これは大掛かりな解決策ですが、私はこれまでのところ最高のものを考え出すことができます。

本当に助けていただければ幸いです。既存のトリガやプロシージャを変更することはできませんが、既存のロジック(新しいテーブルやon insertトリガなど)には絶対に影響しない場合は、dbに何かを追加できます。

要約:ちょうど私がHibernateのsave呼び出しで挿入した行のIDを取得する方法を見つける必要があります。そのinstead of insertトリガのため、hibernateは常にidentity = 0を返します。私は1つのトランザクション中にいくつかの他のテーブルで挿入を行う必要があるので、そのIDを取得する方法を見つける必要があります。

+0

あなたが何をしようとしているのかは明らかではありませんが、OUTPUT句を挿入する必要があります。これは、一度に挿入されたすべての値を返すことができます(トリガーは、操作ごとに1回、行ごとに1回ではありません)。出力値を使用して、新しく作成されたID値と共に他のテーブルに挿入することができます。 –

+0

こんにちは@SeanLange私はqnを更新しますが、私はちょうどHibernateの 'save'呼び出しで挿入した行のIDを取得する方法を見つける必要があります。そのため、hibernateは常に1を返します。あるトランザクション中に他のいくつかのテーブルで挿入を行う必要があるため、そのIDを取得する方法を見つける必要があります。 –

+0

@SeanLangeこのOUTPUT節はどこに置かれますか?私はその '挿入の代わりに'トリガーを変更することはできません。 –

答えて

0

私は私の質問の答えを見つけたと思う。 @ SeanLangeのコメントに返信する:私は実際には挿入コードを編集することはできません。これは別のアプリケーションによって行われ、変更には時間がかかりすぎる(またはこれは起こりません - これは従来のアプリケーションです)。私がやったのは同じテーブルに別のトリガーon insertを挿入することでした。私は既存のinstead of insertトリガの操作の順序を知っているので、最後のinsert操作がテーブルにあることがわかります。つまり、私のon insertトリガはその直後にトリガされます。そのトリガの範囲では、私はIDを引き出すのinsertedテーブルへのアクセスを持っています。

CREATE TRIGGER Client_OnInsert ON myClientTable 
FOR INSERT 
AS 
BEGIN 
    DECLARE @ID int; 
    SET @ID = (select ClientID from inserted); 
    INSERT INTO ModClient (modClientId) 
    OUTPUT @ID 
    VALUES (@ID); 
END 
GO 

は、その後休止状態(私はもうsave()を使用することはできませんので)で、私はこの挿入を行うにはNativeQueryを使用しています。私はパラメータを設定し、Listを返すNativeQueryのメソッドlist()を実行します。最初と唯一の引数は私が望むIDです。

これはかさばる方法です、私は知っています。人々に際立つことが本当に悪いことがあれば、私に知らせてください。私は本当にこれに関するいくつかのフィードバックに感謝します。しかし、私はこの回答を、これまでに働いた潜在的な回答として投稿したかったのですが、それがとても良いというわけではありません。このソリューションが機能するためには、別の小さなテーブルModClientを作成する必要がありました。これは、この正確な目的のためにtemp idストレージとして使用する必要があります。

関連する問題