有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java在insert触发器之后获取标识,而不是insert触发器

我正在使用Hibernate和MSSQL server编写与现有数据库集成的软件。在我需要插入的表上有一个instead of insert触发器,它把@@Identity搞砸了,这意味着在Hibernate的save上我无法获取插入行的id。我无法控制触发器(无法修改它)。我看到了this问题,但它涉及到程序,我的触发器没有,所以我认为我的问题已经足够不同了。我不能发布整个触发器,但希望我可以发布足够多的内容,让大家明白这一点:

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;

我想知道是否有可靠的方法来获取插入行的id?我想到并尝试的一个解决方案是在将新插入的行写入我添加到db的新表的同一个表上安装on insert触发器。我会把那张桌子当作队列。在Hibernate中进行事务提交之后,我可以进入该表并使用刚才插入的信息运行一个select(我仍然可以从相同的方法范围访问它),然后我可以获取id并最终删除该行。这是一个庞大的解决方案,但迄今为止我能想到的最好的解决方案

非常感谢你的帮助。我不能修改现有的触发器和过程,但如果db绝对不影响现有逻辑(如新表和on insert触发器),我可以向db中添加一些内容

总而言之:我需要找到一种方法来获取刚才用Hibernate的save调用插入的行的ID。由于instead of insert触发器,hibernate总是返回identity=0。我需要找到一种获取该ID的方法,因为我需要在一个事务期间在其他几个表中进行插入


共 (1) 个答案

  1. # 1 楼答案

    我想我找到了我问题的答案。回复@SeanLange的评论:我实际上无法编辑插入代码-这是由另一个应用程序完成的,并且查询更改将花费太长时间(或者不会发生-这是一个遗留应用程序)。我所做的是在同一个表上插入另一个触发器on insert。因为我知道现有instead of insert触发器中的操作顺序,所以我可以看到最后一个insert操作将在我想要的表中,这意味着我的on insert触发器将在那之后立即触发。在该触发器的范围内,我可以访问inserted表,并从中提取id

    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
    

    然后在Hibernate中(因为我不能再使用save()),我使用NativeQuery来执行这个插入。我设置参数并运行NativeQuery的list()方法,该方法返回一个List,其中第一个也是唯一一个参数是我想要的id

    我知道,这条路太大了。如果有什么非常糟糕的事情会在人们面前突出,请让我知道。我真的很希望能得到一些反馈。然而,我想把这个答案作为一个迄今为止有效的潜在答案发布,但这并不意味着它非常好。为了使这个解决方案起作用,我必须创建另一个小表ModClient,我必须使用它作为临时id存储,以达到这个确切的目的