代码之家  ›  专栏  ›  技术社区  ›  DMJ

如果某个特定列存在,则更新该列;如果该列不存在,则更新不失败

  •  1
  • DMJ  · 技术社区  · 3 年前

    我想知道是否有一种方法,在表上执行更新时,如果某个列存在,我可以更新它,但是如果该列不存在,我仍然可以成功地执行。

    例如,假设我有这样一个基本的update语句:

    UPDATE some_table
    SET col1 = "some value",
        col2 = "another value",
        col3 = "a third value"
    WHERE id = 567
    

    col3 当查询运行时,语句实际上不存在,语句仍然执行并 col1 col2 是否仍用新值更新?

    IF CASE 价值

    我知道我可以查询数据库中是否存在该列,然后使用一个简单的if条件在应用程序代码中使用另一个查询。但是,这需要我查询数据库两次:一次查看列是否存在,另一次实际更新它。如果可能的话,我更喜欢使用一个SQL查询。我觉得应用程序代码可能会开始变得笨拙,因为有很多额外的代码来检查这个或那个列的存在,并有条件地构建查询,而不是只使用一个查询,不管应用程序当时运行的是哪个数据库。

    澄清一下,任何给定的应用程序实例都只在一个数据库上运行;每个数据库都有一个不同的应用程序实例,但这些实例都将运行相同的代码。这些都是遗留代码也依赖的遗留数据库,因此我不想修改数据库中的实际结构以使它们更加一致,以免破坏遗留代码。

    1 回复  |  直到 3 年前
        1
  •  1
  •   Bill Karwin    3 年前

    不,SQL查询的语法(包括引用的所有列标识符)必须在解析时固定, 之前

    给定的更新要么完全成功,要么完全失败。无法更新 一些 如果查询未能更新所有列,则返回列的。

    您有两个选择:

    • INFORMATION_SCHEMA.COLUMNS 首先,检查给定模式的表中存在哪些列。然后格式化UPDATE查询,包括子句,以便仅当该列存在于表的实例中时才设置该列。

    或者。。。

    • 运行几个UPDATE语句,每个要更新的列对应一个。每个语句都将独立地成功或失败,但您可以捕获错误并继续执行其余语句。您可以将所有这些语句放在一个事务中,这样无论有多少个语句成功(单个失败的语句不会回滚事务),更改集都将以原子方式提交。

    无论哪种方式,都需要编写更多的代码。这就是支持这种可变表结构不可避免的成本。