【问题标题】:Update through stored procedure in SQL Server通过 SQL Server 中的存储过程进行更新
【发布时间】:2016-04-05 12:40:39
【问题描述】:

我有三个表Table1Table2Table3。我在 Table1-> Tier1Tier2Flag 中有三列 may or may not be null 。我将根据公共列和updating 这三列加入这些表。

我的代码如下:

ALTER PROCEDURE [dbo].[SpUpdateTable]
AS     
BEGIN 
     SET NOCOUNT ON;

     BEGIN TRANSACTION;
     BEGIN TRY    

        UPDATE Table1  
        SET Tier_1 = tbl3.T1, Modify_Date = SYSDATETIME()
        FROM Table1 tbl1
        JOIN Table2 tbl2 ON tbl1.CommonColumn1 = tbl2.CommonColumn1
        JOIN Table3 tbl3 ON tbl2.CommonColumn2 = tbl3.CommonColumn2
        WHERE tbl1.BrandName = 'Dell' AND 
        (tbl3.T1 IS NOT NULL AND tbl1.Tier_1 IS NULL OR tbl1.Tier_1 <>  tbl3.T1);

        UPDATE Table1  
        SET Tier_2 = tbl3.T2, Modify_Date = SYSDATETIME()
        FROM Table1 tbl1
        JOIN Table2 tbl2 ON tbl1.CommonColumn1 = tbl2.CommonColumn1
        JOIN Table3 tbl3 ON tbl2.CommonColumn2 = tbl3.CommonColumn2
        WHERE tbl1.BrandName = 'Dell' AND 
        (tbl3.T2 IS NOT NULL AND tbl1.Tier_2 IS NULL OR tbl1.Tier_2 <>  tbl3.T2);


        UPDATE Table1  
        SET Flag = tbl3.Flag, Modify_Date = SYSDATETIME()
        FROM Table1 tbl1
        JOIN Table2 tbl2 ON tbl1.CommonColumn1 = tbl2.CommonColumn1
        JOIN Table3 tbl3 ON tbl2.CommonColumn2 = tbl3.CommonColumn2
        WHERE tbl1.BrandName = 'Dell' AND 
        (tbl3.Flag IS NOT NULL AND tbl1.Flag IS NULL OR tbl1.Flag <> tbl3.Flag);

   END TRY 
   BEGIN CATCH
         IF @@TRANSCOUNT > 0
            ROLLBACK TRANSACTION;
            RETURN;        
   END CATCH

   IF @@TRANSCOUNT > 0
      COMMIT TRANSACTION;
END

好吧,我的代码正在一一更新列。我更关心hitting database 更新每一列,有什么方法可以使用单个更新查询来做到这一点?

【问题讨论】:

  • 旁注:您应该为您的存储过程使用sp_ 前缀。微软有reserved that prefix for its own use (see Naming Stored Procedures),你确实会在未来某个时候冒着名称冲突的风险。 It's also bad for your stored procedure performance。最好只是简单地避免 sp_ 并使用其他东西作为前缀 - 或者根本不使用前缀!
  • @marc_s :感谢您提供此信息,已更正此问题。但这只是为了命名。我已经更改了无法直接粘贴到此处的实际代码。
  • 并不是说它会帮助你的表现,但你可能会得到更有建设性的答案:几乎不可能一眼就知道发生了什么,感觉太像工作了。是否可以通过Table3Table1 提供更有意义的名称?试着忘记你刚刚写的,并阅读你的 where 子句重复 tblx.Flag 条件。

标签: sql-server join stored-procedures exception-handling sql-update


【解决方案1】:

我会使用这样的东西:

with x as (
    select tbl1.tier_1 tbl1_tier_1, tbl1.tier_2 tbl1_tier_2, tbl1.flag tbl1_flag, tbl3.t1, tbl3.t2, tbl3.flag
    from table1 tbl1
    join table2 tbl2 on tbl1.commoncolumn1 = tbl2.commoncolumn1
    join table3 tbl3 on tbl2.commoncolumn2 = tbl3.commoncolumn2
    where tbl1.brandname = 'Dell' 
)
update x 
set
    tbl1_tier_1 = isnull(tbl1_tier_1, t1),
    tbl1_tier_2 = isnull(tbl1_tier_2, t2),
    tbl1_tier_3 = isnull(tbl1_tier_3, t3),
    modify_date = sysdatetime()

只有当 Table1 为 NULL 时才会更新 Table1 中的值,否则将保留现有值。

【讨论】:

  • 您好,感谢您提供此代码。您的代码仅采用 NULL 的情况,如果列值不同并且我想用我们正在获取的值进行更新怎么办?我也想包含这个场景。
【解决方案2】:

试试这个:

 BEGIN TRY    

    UPDATE Table1  
        SET Modify_Date = SYSDATETIME(),
            Tier_1 = CASE WHEN (tbl3.T1 IS NOT NULL AND tbl1.Tier_1 IS NULL OR tbl1.Tier_1 <>  tbl3.T1) THEN
                        tbl3.T1
                     ELSE 
                        Tier_1 
                     END,
            Tier_2 = CASE WHEN (tbl3.T2 IS NOT NULL AND tbl1.Tier_2 IS NULL OR tbl1.Tier_2 <>  tbl3.T2) THEN
                        tbl3.T2
                     ELSE 
                        Tier_2
                     END,
            Flag = CASE WHEN (tbl3.Flag IS NOT NULL AND tbl1.Flag IS NULL OR tbl1.Flag <> tbl3.Flag) THEN
                        tbl3.Flag
                     ELSE
                        Flag
                     END
    FROM Table1 tbl1
    JOIN Table2 tbl2 ON tbl1.CommonColumn1 = tbl2.CommonColumn1
    JOIN Table3 tbl3 ON tbl2.CommonColumn2 = tbl3.CommonColumn2
    WHERE tbl1.BrandName = 'Dell' 
    AND 
    (
        (tbl3.T1 IS NOT NULL AND tbl1.Tier_1 IS NULL OR tbl1.Tier_1 <>  tbl3.T1)
        OR 
        (tbl3.T2 IS NOT NULL AND tbl1.Tier_2 IS NULL OR tbl1.Tier_2 <>  tbl3.T2)
        OR
        (tbl3.Flag IS NOT NULL AND tbl1.Flag IS NULL OR tbl1.Flag <> tbl3.Flag)
    )
END TRY 
BEGIN CATCH
    --code to catch exception
END CATCH

【讨论】:

  • @TabAlleman 正确,我没有注意到更新是针对不同列的。现已修复。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-10-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-08-26
  • 1970-01-01
  • 2021-09-25
相关资源
最近更新 更多