【问题标题】:Adding column to table and then setting value gives error将列添加到表然后设置值会出错
【发布时间】:2020-05-13 10:19:18
【问题描述】:

我对 SQL 很陌生。我正在使用 SQL Server 2012。我需要执行以下操作:向现有表中添加一列,并使用相同的值填充该列中的所有行。为此,我根据网上搜索得出以下结论:

ALTER TABLE myTable ADD myNewColumn VARCHAR(50) NULL
UPDATE myTable SET myNewColumn = 'test'

问题是在 SQL Server 中,第二条语句出现以下错误:

列名“myNewColumn”无效

所以,我的猜测是第一条语句没有创建一个名为 myNewColumn 的新列。

【问题讨论】:

  • 每条语句后都需要使用GO

标签: sql sql-server sql-server-2012


【解决方案1】:

您需要分批执行更新。否则,SQL Server 会在尝试运行创建它的ALTER 之前尝试解析并验证该列是否存在。您在解析时得到无效的列名,而不是在运行时。

一种解决方法是在两个批次之间使用GO

ALTER TABLE dbo.myTable ADD myNewColumn VARCHAR(50) NULL;
GO
UPDATE dbo.myTable SET myNewColumn = 'test';

Always use schema prefixes to reference objectsalways terminate statements with semi-colons.)

但这仅适用于 Management Studio 和其他某些客户端应用程序,因为它实际上不是 T-SQL 语言的一部分;这些客户端工具将其视为批次分隔符,并告诉他们分别提交和评估这两个批次。它不适用于以其他方式提交给 SQL Server 的代码块和作为单个批次,例如在存储过程的主体中:

CREATE PROCEDURE dbo.foo
AS
BEGIN
  SET NOCOUNT ON;
  SELECT 1;
  GO
  SELECT 2;
END
GO

这会产生以下错误,因为它实际上将存储过程拆分为两个单独的批次:

消息 102,级别 15,状态 1,过程 foo,第 8 行
';' 附近的语法不正确。
消息 102,第 15 级,状态 1,第 11 行
“END”附近的语法不正确。

作为一种不同的解决方法,您可以通过在动态 SQL 中执行更新来强制更新到自己的批处理中。

DECLARE @sql NVARCHAR(MAX), @value VARCHAR(50) = 'test';

ALTER TABLE dbo.myTable ADD myNewColumn VARCHAR(50) NULL;

SET @sql = N'UPDATE dbo.myTable SET myNewColumn = @value;';

EXEC sp_executesql @sql, N'@value VARCHAR(50)', @value;

(Why you should use EXEC sp_executesql vs. EXEC(@sql).)

另一种解决方法;一步完成添加和更新:

ALTER TABLE dbo.myTable ADD myNewColumn VARCHAR(50) DEFAULT 'test' WITH VALUES;

(如果您实际上不希望任何未来的行在可能导致该行为的情况下继承该值,则可以稍后删除默认约束。)

【讨论】:

  • 如果他们在企业版上,“With Values”建议将仅在 2012 年成为元数据。
  • @MartinSmith 是的,是的,感谢您提出该增强功能。 Remus 深深地爱上了那个:rusanu.com/2011/07/13/…
【解决方案2】:

在你的 alter 语句后加上 GO 一词

【讨论】:

    【解决方案3】:

    Alterupdate 不能同时执行。您需要使用内置存储过程将其隔离以执行更新语句,如下所示:

    ALTER TABLE myTable ADD myNewColumn VARCHAR(50) NULL
    
    Exec sp_executesql N'UPDATE myTable SET myNewColumn = ''test'''
    

    这肯定能解决这个问题。

    【讨论】:

      【解决方案4】:

      尝试类似:

      ALTER TABLE myTable ADD myNewColumn VARCHAR(50) NULL DEFAULT("Something")
      

      您的代码的问题是该列在查询完成之前不存在。所以在那之前你可以参考它。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-02-20
        • 2012-10-05
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多