这个SQL语法出了什么问题?

时间:2013-10-16 10:29:52

标签: sql-server sql-server-2008 ssms

我被告知要对我们数据库的模式进行一些更改,因此我编写了以下脚本来执行以下操作:

  1. 根据另一个表的值
  2. 更新表的值
  3. 删除包含指向其他表的ID的列
  4. 只有当id_to_other_table当然存在

    时才应执行整个脚本

    这是我的SQL

    IF EXISTS (
    SELECT * FROM INFORMATION_SCHEMA.COLUMNS 
    WHERE COLUMN_NAME = 'title_id' AND TABLE_NAME = 'my_table'
    )
    BEGIN   
        UPDATE
            my_table
        SET
            my_table.title = other_table.value
            FROM
            my_table
            INNER JOIN
            other_table
        ON
            my_table.title_id = other_table.id
        WHERE other_table.language_id = 1 --hardcoded
    
        ALTER TABLE my_table
        DROP COLUMN title_id
    END
    

    第一次运行此SQL时,代码正确执行。当我再次运行它而不是什么都不做时,它会给我以下错误,指向ON的{​​{1}}部分之后的行:

    JOIN

    如果我将Invalid column name 'my_table.title_id' - BEGIN块的内容替换为END,则它会正确显示任何内容,因此print "Does the column exists?" - BEGIN块正在以预先结束的方式结束出于某种原因...

    有什么想法吗?

2 个答案:

答案 0 :(得分:1)

实际上,生成错误的原因是您在块(批处理)中执行多个sql语句。只要您有批次,就会适用一些规则。由于您在1批次内更改并引用同一个表,因此会发生编译错误。 一旦分离了两个sql语句,就不会出现编译错误:

    IF EXISTS (
    SELECT * FROM INFORMATION_SCHEMA.COLUMNS 
    WHERE COLUMN_NAME = 'title_id' AND TABLE_NAME = 'my_table'
    )
    BEGIN   
        UPDATE
            my_table
        SET
            my_table.title = other_table.value
            FROM
            my_table
            INNER JOIN
            other_table
        ON
           my_table.title_id = other_table.id
        WHERE other_table.language_id = 1 --hardcoded

        END

    IF EXISTS (
    SELECT * FROM INFORMATION_SCHEMA.COLUMNS 
    WHERE COLUMN_NAME = 'title_id' AND TABLE_NAME = 'my_table'
    )
    BEGIN   
        ALTER TABLE my_table
        DROP COLUMN title_id
    END

答案 1 :(得分:0)

在执行之前将SQL解析为一个整体。因此,尽管没有运行条件语句,仍然会检查它们的有效性。您可以将命令封装为字符串,并使用execsp_executesql来运行它们,作为解决方法。