【问题标题】:How to update a table and ignore a computed column if it is computed but update it if it is not computed如果已计算,如何更新表并忽略计算列,但如果未计算则更新它
【发布时间】:2019-06-10 12:04:47
【问题描述】:

我有不同版本的 SQL Server 数据库:

  • DB 1 中,“IsReadOnly”列是计算列
  • DB 2 中,列“IsReadOnly”是一个非计算列

我需要创建一个适用于两个版本的标准脚本:

IF EXISTS (SELECT 1 FROM sys.columns 
           WHERE Name = N'IsReadOnly'
             AND Object_ID = OBJECT_ID(N'dbo.TableA')
             AND is_computed = 0) 
BEGIN
    UPDATE TableA   
    SET IsReadOnly = @IsReadOnly    
    WHERE Id = @ID 
END

运行上述时,它适用于 is_computed = 0 的版本。但在 is_computed = 1 的版本上运行时,我得到:

消息 271,第 16 层,状态 1,第 322 行
无法修改“IsReadOnly”列,因为它要么是计算列,要么是 UNION 运算符的结果

非常感谢任何帮助。谢谢

【问题讨论】:

    标签: sql-server calculated-columns


    【解决方案1】:

    这是一个编译时与执行时的问题。该错误发生在无法更新值的数据库的编译时。

    您可以使用动态 SQL 绕过它:

    IF EXISTS( SELECT 1 FROM sys.columns 
               WHERE Name = N'IsReadOnly'
               AND Object_ID = Object_ID(N'dbo.TableA')
               AND is_computed = 0          
              ) 
    BEGIN
        EXEC sp_execute_sql N'
    Update TableA    
       Set IsReadOnly = @IsReadOnly     
       Where Id = @ID',
                           N'@IsReadOnly int, @ID int',  -- guessing at the types
                           @IsReadOnly=@IsReadOnly, @ID=@ID;
    END
    

    不过,更简单的方法可能是 TRY/CATCH 块:

    BEGIN TRY
        Update TableA    
           Set IsReadOnly = @IsReadOnly     
           Where Id = @ID ;
    END TRY
    BEGIN CATCH
        -- Check for the particular error and do something when that occurs
    END CATCH;
    

    【讨论】:

    • 太棒了。非常感谢你。我现在就试试。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-07-02
    • 2021-07-04
    • 1970-01-01
    • 1970-01-01
    • 2018-11-22
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多