首页 > 解决方案 > 一次更新两个表,其中第一个表的值和一个变量

问题描述

我正在尝试仅在具有值为 NULL 的第一行中使用传递的变量进行更新(多行在此列中可能具有 NULL,但我只需要一个),然后我需要使行受到影响(主键)并用它更新另一个表。

这是我的两个表的样子:

table1
id | some_value | ref_table2_id_fk

table2
id |    name    | ref_table1_id_fk

在我的存储过程中,我将传递的值作为@passed as int,然后我尝试以下操作:

BEGIN
    SET NOCOUNT ON;
    DECLARE @id AS INT;
    DECLARE @temp TABLE (id int);
     BEGIN TRANSACTION;
     BEGIN TRY

        UPDATE TOP (1) [dbo].table1
            SET ref_table2_id_fk = @passed
            OUTPUT inserted.id INTO @temp
            WHERE ref_table2_id_fk = NULL

        UPDATE [dbo].table2
            SET ref_table1_id_fk = @temp.id
            FROM table2
            JOIN @temp i on i.id = table2.id;

        SET @id = @@IDENTITY

     END TRY
     BEGIN CATCH
        IF @@TRANCOUNT > 0
        BEGIN
         --some error
         ROLLBACK TRANSACTION;
         RETURN 0;
        END
     END CATCH;

      IF @@TRANCOUNT > 0
        BEGIN
         --success
         COMMIT TRANSACTION;     
         RETURN @Id;
        END

END

正如 Dale @@identity 所指出的,在更新中不起作用。我的目的是简单地知道交易是否通过。

标签: sqlsql-server

解决方案


我认为以下代码可以满足您的要求。固定的东西:

  1. where ref_table2_id_fk = null应该where ref_table2_id_fk is null

  2. 您不能TOPupdate需要子查询来获取 id 的语句中使用。

  3. 您没有提供id加入@temp-table2您需要table1id 和table2id 来进行加入更新。

  4. 如果我理解你的逻辑,你想要返回的 id 是@passed- 你已经有了它。

  5. @temp.id应该是i.id因为你(正确地)给它起了别名

    declare @Passed int = 3;

    declare @table1 table (id int, some_value varchar(12), ref_table2_id_fk int);
    declare @table2 table (id int, some_value varchar(12), ref_table1_id_fk int);

    insert into @table1 (id)
      select 1 union all select 2;

    insert into @table2 (id)
      select 3 union all select 4;

    select * from @table1;
    select * from @table2;

    DECLARE @id AS INT, @Result bit = 0;
    DECLARE @temp TABLE (id int, fk int);

    BEGIN TRANSACTION;
    BEGIN TRY

      UPDATE @table1
        SET ref_table2_id_fk = @passed
      OUTPUT @passed, inserted.id INTO @temp
      WHERE id = (
        select top 1 id
        from @table1
        where ref_table2_id_fk is NULL
        -- Optionally order by if you have a priority here
      );

      UPDATE T2
        SET ref_table1_id_fk = i.fk
      FROM @table2 T2
      JOIN @temp i on i.id = T2.id
      where T2.id = @passed;

      -- If we get here then everything worked
      -- Return @Result at the end of the proc
      SET @Result = 1;

    END TRY
    begin catch
      no_op:;
    end catch

    select * from @table1;
    select * from @table2;

推荐阅读