创建列后,sql server update上的列名无效

Tho*_*hom 21 sql t-sql sql-server ddl

有没有人看到这个SQL Server代码有什么问题?

IF NOT EXISTS(SELECT *
              FROM   sys.columns
              WHERE  Name = 'OPT_LOCK'
                     AND object_ID = Object_id('REP_DSGN_SEC_GRP_LNK'))
  BEGIN
      ALTER TABLE REP_DSGN_SEC_GRP_LNK
        ADD OPT_LOCK NUMERIC(10, 0)

      UPDATE REP_DSGN_SEC_GRP_LNK
      SET    OPT_LOCK = 0

      ALTER TABLE REP_DSGN_SEC_GRP_LNK
        ALTER COLUMN OPT_LOCK NUMERIC(10, 0) NOT NULL
  END; 
Run Code Online (Sandbox Code Playgroud)

当我运行这个时,我得到:

消息207,级别16,状态1,行3
无效的列名称"OPT_LOCK".

在更新命令上.

谢谢.

Mar*_*ith 37

在这种情况下,您可以通过将列添加NOT NULL为一个并根据我的答案在一个语句中设置现有行的值来避免此问题.

更一般地说,问题是解析/编译问题.SQL Server尝试在执行任何语句之前编译批处理中的所有语句.

当一个语句引用一个根本不存在的表时,该语句将被延迟编译.当表已存在时,如果引用非现有列,则会引发错误.解决此问题的最佳方法是在与DML不同的批处理中执行DDL.

如果语句都引用现有表中的非现有列和不存在的表,则在推迟编译之前可能会抛出错误,也可能不会抛出错误.

您可以在不同的批次中提交它(例如,通过GO在客户端工具中使用批处理分隔符),也可以在使用EXEC或单独编译的子范围中执行它EXEC sp_executesql.

第一种方法需要您重构代码,因为IF ...无法跨越批次.

IF NOT EXISTS(SELECT *
              FROM   sys.columns
              WHERE  Name = 'OPT_LOCK'
                     AND object_ID = Object_id('REP_DSGN_SEC_GRP_LNK'))
  BEGIN
      ALTER TABLE REP_DSGN_SEC_GRP_LNK
        ADD OPT_LOCK NUMERIC(10, 0)

      EXEC('UPDATE REP_DSGN_SEC_GRP_LNK SET OPT_LOCK = 0');

      ALTER TABLE REP_DSGN_SEC_GRP_LNK
        ALTER COLUMN OPT_LOCK NUMERIC(10, 0) NOT NULL
  END; 
Run Code Online (Sandbox Code Playgroud)

  • 这是我多年来一直使用的方法,每当我们想要添加一个新列并用数据填充它时,我们总是不得不采用这种笨拙的动态sql路由. (3认同)
  • 接近的EXEC为我工作.谢谢! (2认同)