这个sql出了什么问题?

时间:2011-07-21 08:12:10

标签: tsql transactions batch-file

执行以下脚本时,出现错误:

  

消息207,级别16,状态1,行15无效的列名称“b”。

任何人都可以解释一下吗?感谢。

DROP TABLE ttt;
CREATE TABLE ttt(a nvarchar)

IF NOT EXISTS ( SELECT  *
                FROM    sys.columns
                WHERE   object_id = OBJECT_ID('dbo.ttt')
                        AND name = 'b' )
    AND EXISTS ( SELECT *
                 FROM   sys.columns
                 WHERE  object_id = OBJECT_ID('dbo.ttt')
                        AND name = 'a' ) 
    BEGIN

        ALTER TABLE [dbo].ttt ADD b NVARCHAR

        UPDATE  [dbo].ttt
        SET     b = a

        ALTER TABLE [dbo].ttt DROP COLUMN a
    END

2 个答案:

答案 0 :(得分:2)

它试图在执行第一个语句之前编译所有这些语句:

 ALTER TABLE [dbo].ttt ADD b NVARCHAR

    UPDATE  [dbo].ttt
    SET     b = a

    ALTER TABLE [dbo].ttt DROP COLUMN a

(事实上,它试图编译整批,而不仅仅是这些语句,但重点仍然存在 - 在它尝试编译UPDATE时,该列确实如此不存在)

当它试图编译UPDATE语句时,它会查询表元数据并正确地发现该列不存在。

尝试EXEC更新声明。

    EXEC('UPDATE  [dbo].ttt
    SET     b = a');

而且,Oded说你可能想要指定列的大小(否则,它默认为有史以来最无意义的数据类型 - nvarchar(1)


此脚本绝对可以正常运行:

CREATE TABLE ttt(a nvarchar)

IF NOT EXISTS ( SELECT  *
                FROM    sys.columns
                WHERE   object_id = OBJECT_ID('dbo.ttt')
                        AND name = 'b' )
    AND EXISTS ( SELECT *
                 FROM   sys.columns
                 WHERE  object_id = OBJECT_ID('dbo.ttt')
                        AND name = 'a' ) 
    BEGIN

        ALTER TABLE [dbo].ttt ADD b NVARCHAR

        EXEC('UPDATE  [dbo].ttt
        SET     b = a');

        ALTER TABLE [dbo].ttt DROP COLUMN a
    END

答案 1 :(得分:2)

如果您将代码放在存储过程中,它应该可以工作。在创建过程时,只需确保表中存在a列和b列。然后在创建过程后,您可以删除表并进行测试。