SQL Server:IF语句的结果不一致

时间:2013-09-06 12:05:07

标签: .net sql sql-server

我正在进行数据迁移,我目前正在为最糟糕的情况实现反向脚本。我现在可能有点累了但是我无法理解这件事 - 所以也许你可以帮忙。

我有以下SQL:

IF NOT EXISTS(SELECT * FROM sys.columns WHERE Name = N'FileId' AND Object_ID = Object_ID(N'[FileData]'))
AND EXISTS(SELECT * FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = 'FileData' 
AND COLUMN_NAME = 'FileDataId')
BEGIN
    SELECT 1;
    --ALTER TABLE [FileData] ADD [FileId] [uniqueidentifier] NULL
    --ALTER TABLE [FileData] DROP CONSTRAINT PK_FileData

    --UPDATE [FileData] SET [FileData].[FileId] = [File].[FileId] 
    --FROM [FileData] INNER JOIN [File] on [FileData].FileDataId = [File].FileData

    --ALTER TABLE [FileData] ALTER COLUMN [FileId] [uniqueidentifier] NOT NULL
    --ALTER TABLE [FileData] ADD CONSTRAINT PK_FileData PRIMARY KEY (FileId)
END
ELSE
BEGIN
    SELECT 0;
END

运行上面的查询将始终返回0 - 这是正确的,因为FileName列确实存在而FileDataId不存在。到目前为止一切都很好。

当我删除第一个select语句并取消注释alter和update代码时。我收到错误:

  

无效的列名'FileDataId'

查询我在取消注释后运行

IF NOT EXISTS(SELECT * FROM sys.columns WHERE Name = N'FileId' AND Object_ID = Object_ID(N'[FileData]'))
AND EXISTS(SELECT * FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = 'FileData' 
AND COLUMN_NAME = 'FileDataId')
BEGIN
    ALTER TABLE [FileData] ADD [FileId] [uniqueidentifier] NULL
    ALTER TABLE [FileData] DROP CONSTRAINT PK_FileData

    UPDATE [FileData] SET [FileData].[FileId] = [File].[FileId] 
    FROM [FileData] INNER JOIN [File] on [FileData].FileDataId = [File].FileData

    ALTER TABLE [FileData] ALTER COLUMN [FileId] [uniqueidentifier] NOT NULL
    ALTER TABLE [FileData] ADD CONSTRAINT PK_FileData PRIMARY KEY (FileId)
END
ELSE
BEGIN
    SELECT 0;
END

我的问题:
为什么我始终从IF语句中获得相同的false结果,但是当我取消注释true - 子句中的代码时,它会突然输入。我在这里完全遗漏了什么吗?

1 个答案:

答案 0 :(得分:3)

SQL Server希望在执行之前编译整个批处理。它无法编译它,因为该列不存在,因此它永远不会执行IF语句。

您必须使用dynamic SQL,以便在您确认其存在之前,它不会尝试编译引用该列的语句。

IF NOT EXISTS(SELECT * FROM sys.columns WHERE Name = N'FileId' AND Object_ID = Object_ID(N'[FileData]'))
AND EXISTS(SELECT * FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = 'FileData' 
AND COLUMN_NAME = 'FileDataId')
BEGIN
    EXEC('ALTER TABLE [FileData] ADD [FileId] [uniqueidentifier] NULL')
    EXEC('ALTER TABLE [FileData] DROP CONSTRAINT PK_FileData')

    EXEC('UPDATE [FileData] SET [FileData].[FileId] = [File].[FileId]
    FROM [FileData] INNER JOIN [File] on [FileData].FileDataId = [File].FileData')

    EXEC('ALTER TABLE [FileData] ALTER COLUMN [FileId] [uniqueidentifier] NOT NULL')
    EXEC('ALTER TABLE [FileData] ADD CONSTRAINT PK_FileData PRIMARY KEY (FileId)')
END
ELSE
BEGIN
    SELECT 0;
END