【问题标题】:How to check whether row was inserted or replaced in SQLite?如何检查 SQLite 中是否插入或替换了行?
【发布时间】:2015-12-06 19:08:07
【问题描述】:

我有一个 SQLite 数据库,我创建了一个这样的唯一索引:

CREATE UNIQUE INDEX [my_unique_idx] ON [my_table] ([field1], [field2]);

现在在我的程序中,我想在my_table 中插入一行INSERT OR REPLACE,如果它被插入,我需要在另一个“从属”表中插入其他行。另一方面,如果该行已更新,我无需执行任何操作。换句话说:

if ( query.exec(
    "insert or replace into my_unique_idx"
    "    (field1, field2, other_field)"
    "  values"
    "    (1, 2, 'foo')"
   ) )
{
    if ( query.is_was_really_inserted() ) // <---- how to ?
    {
        slave_query.exec( "insert into slave_table......
    }
}

我知道,我可以通过几个查询来做到这一点:选择具有适当值的行,如果行不存在,则将数据插入两个表(“主”和“从”),然后更新“主”如果行存在,则为表。
但这使得唯一索引和INSERT OR REPLACE 子句毫无意义。

【问题讨论】:

  • 你使用什么编程语言?
  • 索引加快了搜索记录的速度。仅当您不关心实际发生的情况时,INSERT OR REPLACE 才有用。
  • @CL。谢谢你。当然,我使用索引,但不使用复合索引——一个用于自己的领域。顺便说一句,什么很快:为一个特定字段使用一个索引或为所有字段使用一个索引,这将在 where 中进一步 selects ?
  • 什么索引更有用取决于查询和数据。如果您不了解,请尝试两个索引(运行 ANALYZE 并使用 EXPLAIN QUERY PLAN 检查。)

标签: c++ sql qt sqlite


【解决方案1】:

这似乎可以通过触发器实现。 SQLite documentation 状态:

当发生 UNIQUE 或 PRIMARY KEY 约束违规时,REPLACE 算法会在插入或更新当前行之前删除导致约束违规的预先存在的行,并且命令会继续正常执行。

[...]

当 REPLACE 冲突解决策略删除行以满足约束时,当且仅当启用递归触发器时,删除触发器才会触发。

因此,如果您有删除触发器,您将知道是否有任何行被删除以替换它。

您可以:

  • 使用该触发器更新一些中间表,然后在查询后运行另一个查询以检查哪些行已更新(似乎是最糟糕的解决方案)。

  • 使用该触发器来确保您的数据库一致性(不错,但是代码和脚本之间会有一些逻辑碎片)。

  • 使用 Qt 注册触发器将调用的 DB 事件:请参阅this answer。似乎 SQLite supports event notifications.

【讨论】:

  • 好的,谢谢。但是我怎么知道删除触发器是在我的程序中触发的(不是在 QSLite 中)?请注意,我需要知道它才能在其他表中插入或不插入其他数据。
  • 似乎 SQLite 支持 event notifications。我会试试这个...或者...我会删除OR REPLACE 并在Qt 的程序中使用几个查询。也许这是最简单的决定
  • @borisbn 感谢您的提示,我会将其放在帖子中以供将来参考。祝你好运!
  • 请注意,SQLite 回调仅适用于从 sqlite 库的一个实例中完成的更改。如果您有多个进程或库实例访问同一个数据库,则通知将仅限于每个实例所做的更改。
  • @KubaOber 谢谢。从来不知道
【解决方案2】:

SQLiteConnection 属性 LastInsertRowId 似乎提供了一种更简单的解决方案,具体取决于索引在表中的工作方式。

SQLite Documentation

【讨论】:

  • 我已经测试过这个解决方案——它对我不起作用。在 REPLACE 的情况下,INSERT 或 REPLACE 先删除行,然后再插入新行。所以 LastInsertRowId 在任何情况下都会递增
猜你喜欢
  • 2017-03-21
  • 1970-01-01
  • 2015-03-07
  • 1970-01-01
  • 1970-01-01
  • 2015-05-11
  • 1970-01-01
  • 2012-12-06
  • 1970-01-01
相关资源
最近更新 更多