如果条目不存在,则插入表列

12
在 Liquibase 中,我想在值未设置时插入值。使用普通的插入操作,如果值已经存在,则插入的值将覆盖先前的值。我希望仅在该值不存在时插入该值。这可行吗?
目前,我正在使用下面所示的插入操作:
<insert tableName="state">
  <column name="name" value="fooFoo"/>
  <column name="enabled" valueBoolean="true"/>
</insert>
2个回答

23

正确的做法是使用preConditions

有一个<sqlCheck> preCondition

sqlCheck

执行SQL字符串并检查返回值。SQL必须返回单个行和单个值。要检查行数,使用“count”SQL函数。要检查值范围,请在SQL中执行检查并返回易于比较的值。

<sqlCheck expectedResult="1">SELECT COUNT(1) FROM pg_tables WHERE TABLENAME = 'myRequiredTable'</sqlCheck>

使用它后,你的changeSet将如下所示:

<changeSet id="foo" author="bar">
    <preConditions onFail="MARK_RAN">
        <sqlCheck expectedResult="0">
            SELECT COUNT(*) FROM state WHERE name='fooFoo' AND enabled=true;
        </sqlCheck>
    </preConditions>
    <insert tableName="state">
      <column name="name" value="fooFoo"/>
      <column name="enabled" valueBoolean="true"/>
    </insert>
</changeSet>

1
如果您删除“AND enabled=true”,那么它会变得更好。逻辑应该是:如果“fooFoo”不存在,则添加“fooFoo”和“true”,否则不执行任何操作。 - Adrian

0
您可以参考下面的问题:

MySQL:如果表中不存在,则插入记录

只需在Liquibase中使用标签即可。
希望这可以帮助您。
编辑: INSERT INTO state(name, enabled) SELECT * FROM (SELECT 'fooFoo','true') AS tmp WHERE NOT EXISTS ( SELECT name FROM state WHERE name = 'fooFoo' ) LIMIT 1

我不确定我完全理解如何在Liquibase中使用标签。你能写出完整的答案吗?或许对此进行解释会更好。 - Adrian
这并没有真正回答问题 - 你给出了一个特定于MySQL的答案,但OP并没有说他们正在使用哪个数据库。可以推测,请求的是适用于Liquibase支持的所有数据库的解决方案... - GreyBeardedGeek
你的意思确实是SQL标签。我在另一个地方看到了其他的“标签”,以为你指的是那个。我使用了你的建议并进行了修改。将其复制到你的答案中,我会将其标记为已回答。还请给我一个线程点。INSERT INTO state(name, enabled) SELECT * FROM (SELECT 'fooFoo' AS name, 1 AS enabled) AS tmp WHERE NOT EXISTS ( SELECT name FROM state WHERE name = 'fooFoo') LIMIT 1;是的,这是一个我没有提到的mySQL。 ;) - Adrian
是的,StackOverflow编辑掉了SQL标签,我不得不在它们中间提供空格以显示它们。 - Raushan

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接