2013-03-07 52 views
2

对于Sql Server 2005和2008我想检查列是否已经存在于一个给定的表,并创建它,如果它不。这个新列应该有一个ExistingColumn的默认值。目前我需要使用动态sql来填充新列,因为sql server会抱怨语法错误。将列添加到现有的表和默认值到另一列没有动态sql

这是当前的SQL Server代码:

IF NOT EXISTS (SELECT TOP 1 1 FROM sys.columns WHERE [name] = N'NewColumn' AND OBJECT_ID = OBJECT_ID(N'ExistingTable')) 
BEGIN 
    ALTER TABLE [dbo].[ExistingTable] ADD [NewColumn] VARCHAR(50) NULL; 

    exec sp_executesql N'UPDATE [dbo].[ExistingTable] SET NewColumn = ExistingColumn' 

    ALTER TABLE [dbo].[ExistingTable] ALTER COLUMN [NewColumn] VARCHAR(50) NOT NULL 
END 
GO 

有没有其他的办法来解决这个问题,而不是诉诸动态sql?

+1

为什么不喜欢动态sql作为解决方案? – 2013-03-07 19:03:04

+0

除了没有获得Management Studio的语法高亮和自动完成之外,我对它没有任何问题。对于封面上真正发生的事情更加好奇。 – 2013-03-07 19:04:21

+0

啊,我通常用Print来代替exec,然后在另一个窗口粘贴它不是很亮,但是最好是试图找出附近的错误,意思是 – 2013-03-07 20:44:11

回答

2

由于无论您是在创建列,您都可以执行两个单独的批次。

IF NOT EXISTS (SELECT TOP 1 1 FROM sys.columns WHERE [name] = N'NewColumn' AND OBJECT_ID = OBJECT_ID(N'ExistingTable')) 
    BEGIN 
     ALTER TABLE [dbo].[ExistingTable] ADD [NewColumn] VARCHAR(50) NULL; 
    END 
    GO 
    IF EXISTS (SELECT TOP 1 1 FROM sys.columns WHERE [name] = N'NewColumn' AND OBJECT_ID = OBJECT_ID(N'ExistingTable')) 
    BEGIN 
     IF EXISTS (SELECT 1 FROM [dbo].[ExistingTable] WHERE NewColumn IS NULL) 
     BEGIN 
      UPDATE [dbo].[ExistingTable] SET NewColumn = ExistingColumn 
      ALTER TABLE [dbo].[ExistingTable] ALTER COLUMN [NewColumn] VARCHAR(50) NOT NULL 
     END 
    END 
    GO 
+0

值得注意的是,如果你运行第二个无需运行第一批或第一批错误就自行批量生产;上述所做的是让你摆脱动态SQL。所以如果你正在寻找可重复性,那么你就会陷入困境。 – 2013-03-08 20:47:00

2

SQL Server正在解析您的语句之前您的ALTER运行,并说“嘿,没有这样的列”。解析器不理解IF和其他分支,并且在混合DDL和DML时不能遵循事件序列 - 或者预测事件发生的顺序以及运行时将发生的分支。

延迟名称解析允许您访问对象不存在,但不是不上做对象还不存在。

因此,动态SQL似乎是你必须这样做的方式。