SQL Server:检查表列是否存在并删除行

LIN*_*bee 6 sql sql-server

我目前正在编写一个通用的SQL Server脚本来清理具有更多/更少相同表结构的不同数据库.如果数据库中存在该表,则此脚本要求从表中擦除某些数据.这里是一个脚本示例

IF EXISTS( SELECT * FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = 'TAB1')
  IF EXISTS( SELECT * FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = 'TAB1' AND  COLUMN_NAME = 'COL1')
    delete TAB1 where COL1 not in (select COL2 from TAB2);
Run Code Online (Sandbox Code Playgroud)

作为程序员,我知道如果两个条件块都为假,则不会执行delete命令.但是,当我在SQL中运行它时,它返回

列名称"COL1"无效.

可能我的做法是错误的.有人能指出我正确的方向吗?

Dam*_*ver 7

问题是,SQL Server希望在执行任何批处理之前编译整个批处理.

并且它无法编译批处理,因为缺少列.

因此,您必须确保批处理可以在不尝试编译DELETE语句的情况下进行编译- 因此请将其保留为字符串并强制它单独编译:

IF EXISTS( SELECT * FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = 'TAB1')
  IF EXISTS( SELECT * FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = 'TAB1'
        AND  COLUMN_NAME = 'COL1')
    EXEC sp_executesql 'delete TAB1 where COL1 not in (select COL2 from TAB2);'
Run Code Online (Sandbox Code Playgroud)

你说:

作为程序员,我知道如果两个条件块都为假,则不会执行delete命令.

假设,例如,一个C#背景,你的原始查询就像执行两个反射调用来确定一个类型是否具有特定属性,然后有一行代码直接在该类型的对象上使用该属性 - 如果类型不是"T 拥有的属性,代码是不会编译,所以反射检查永远没有机会执行.