我有一个由
创建的表MyTableCREATE 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'
我怎样才能完成我想要做的事情?
答案 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无法预先解析,因此不会尝试。