如果sql中存在列,如何更新表

时间:2016-07-18 18:46:24

标签: sql-server tsql

我有一个由

创建的表MyTable
CREATE TABLE MyTable
(
    [ID] [bigint] IDENTITY(1,1) NOT NULL,
    [Type] [int] NOT NULL,
    [CreatedDate] [datetime] NOT NULL,
    [ModifiedDate] [datetime] NOT NULL,
)

我想检查一下我的表中是否存在列,如果存在,我想将数据复制到另一列,然后删除旧列,如下所示:

IF (SELECT COLUMNPROPERTY(OBJECT_ID('MyTable'), 'Timestamp', 'Precision')) IS NOT NULL
BEGIN
    UPDATE [dbo].[MyTable]
    SET [CreatedDate] = [Timestamp]

    ALTER TABLE [dbo].[MyTable]
    DROP COLUMN [Timestamp]
END
GO

然而,当我尝试运行时,我收到一个错误:

Invalid column name 'Timestamp'

我怎样才能完成我想要做的事情?

2 个答案:

答案 0 :(得分:6)

这是一个编译问题。

如果在编译批处理时表格不存在,则所有工作正常,因为引用该表的语句将受延迟编译的影响。但是对于预先存在的表,您将尝试编译不存在的列中的所有语句和空白时遇到此问题。

您可以将代码推送到子批处理中,以便仅在命中该分支时进行编译。

IF (SELECT COLUMNPROPERTY(OBJECT_ID('MyTable'), 'Timestamp', 'Precision')) IS NOT NULL
BEGIN
EXEC('
    UPDATE [dbo].[MyTable]
    SET [CreatedDate] = [Timestamp]

    ALTER TABLE [dbo].[MyTable]
    DROP COLUMN [Timestamp]
    ')
END
GO

如果您只是想重命名列

EXEC sys.sp_rename 'dbo.MyTable.[TimeStamp]' , 'CreatedDate', 'COLUMN'

虽然会更容易(从CreatedDate列不存在的位置开始)。

答案 1 :(得分:0)

您必须首先使用ALTER TABLE语句创建[Timestamp]列。

其余的应该运行。

根据评论进行编辑(我知道此信息在SO上的其他地方重复,但我无法找到它):

好的,遗憾的是,SQL Server中的IF条件不允许您忽略不解析的代码。发生的事情是SQL Server正在查看您的命令,并解析每个语句以确保它是有效的。

当它执行此操作时,SQL Server不够聪明,无法确定如果没有,则无法到达无效语句(需要UPDATE存在的[TimeStamp][TimeStamp]

换句话说,您不能编写一个SQL命令,该命令需要一个不存在的列,即使您将该命令嵌套在IF条件中也不会被触及。 SQL Server将解析整个语句,并且在测试IF条件之前不允许它运行。

常用的解决方法是动态SQL,SQL Server无法预先解析,因此不会尝试。