【问题标题】:Can not update newly created column无法更新新创建的列
【发布时间】:2020-06-23 13:21:46
【问题描述】:

您好,我正在更改一个 SQL 表,我想在其中添加一个新列 A,然后根据另一列 B 的值设置其默认值。我该怎么做?

到目前为止我已经尝试过:

IF NOT EXISTS(SELECT *FROM INFORMATION_SCHEMA.COLUMNS where TABLE_NAME='T' AND COLUMN_NAME='B')
BEGIN
ALTER TABLE T ADD B bit default 0;
UPDATE T
SET B = A

我不断收到错误:

Msg 207, Level 16, State 1, Line 23
Invalid column name 'B'.

P.S:我想原子地执行这两个语句(更改表并更新新创建的列)

我原以为这是MSSQL 中的Intellisense 的问题,但能够按顺序运行命令。

更新

我也试过分成两条语句,还是没用:

IF NOT EXISTS(SELECT *FROM INFORMATION_SCHEMA.COLUMNS 
              WHERE TABLE_NAME='T' AND COLUMN_NAME='B')
ALTER TABLE T ADD B bit default NULL;

UPDATE T
SET B = A
WHERE B = NULL
END

【问题讨论】:

  • 为什么不把它变成一个计算列?
  • 我不知道将其作为计算列有什么影响。这是一个完整的列,我将在未来对其进行更新。我只需要一种创建和初始化它的方法。

标签: sql-server transactions alter


【解决方案1】:

在运行批处理之前,数据引擎会对其进行解析,并引发任何语法错误和无效的对象引用。不幸的是,一些 DDL 语句不计入后面的语句。首先,如果我们CREATE 并尝试将INSERT 放入一个表中,这可以正常工作:

CREATE TABLE dbo.YourTable (A bit);

INSERT INTO dbo.YourTable (A)
VALUES(1),(0),(1),(1),(0);

另一方面,如果我们尝试(在一个单独的批次中)ALTER 表,然后UPDATE 所述列的值,则批次将失败(如您的示例):

ALTER TABLE YourTable ADD B bit default 0;

UPDATE YourTable
SET B = A

一种方法是将语句分成单独的批次,但是,您将无法将这两个语句包装在您的 IF 中。因此,在这种情况下,最好稍后在批处理中解析语句,通过使用sys.sp_executesql 执行它:

IF NOT EXISTS(SELECT *FROM INFORMATION_SCHEMA.COLUMNS where TABLE_NAME='T' AND COLUMN_NAME='B')
BEGIN
    ALTER TABLE T ADD B bit default 0;
    EXEC sys.sp_executesql N'UPDATE T SET B = A;';
END

【讨论】:

  • 这个sys.sp_executesql 是做什么的? .它基本上是在运行时完成的吗?像在编译时忽略结构之类的东西?它是否执行动态查询?我也试过 2 语句无济于事
  • 它做到了“它在锡上所说的”,@BercoviciAdrian。它执行sql。 sp_executesql
  • UPDATE 语句仍然在相同的范围和批次中,尽管在那个更新中,@BercoviciAdrian,所以它仍然会失败。在 2 个语句之间添加换行符不会改变任何内容。
【解决方案2】:

您需要在 alter 和 update 之间使用“GO”命令。

ALTER TABLE YourTable ADD B bit default 0;
GO
UPDATE YourTable
SET B = A

或

 IF NOT EXISTS(SELECT *FROM INFORMATION_SCHEMA.COLUMNS where TABLE_NAME='T' AND COLUMN_NAME='B')
    BEGIN
      ALTER TABLE T ADD B bit default 0;
      EXEC ('UPDATE product SET B = 1')
END

IF NOT EXISTS(SELECT *FROM INFORMATION_SCHEMA.COLUMNS where TABLE_NAME='T' AND COLUMN_NAME='C')
    BEGIN
      ALTER TABLE T ADD C varchar(20) default null;
      EXEC ('UPDATE product SET C = ''test''')
END

【讨论】:

    猜你喜欢
    • 2012-08-12
    • 1970-01-01
    • 2023-02-24
    • 2019-04-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-10-30
    • 2015-04-25
    相关资源
    最近更新 更多