Delete SQL 将按什么顺序执行?

In what sequence will the Delete SQL execute?

参考我之前的帖子。

1

为 IBM i(As400、Db2)使用 DB2。

我正在执行以下 sql 作为凌晨 3 点的清理脚本。

DELETE FROM p6prodpf A WHERE (0 = (SELECT COUNT(*) FROM P6OPIPF B WHERE   B.OPIID = A.OPIID))

我有一个不同的过程,在这个 sql 运行的同时插入两条记录,第一条记录是 P6OPIPF 记录,然后将详细记录插入 P6PRODPF .

问题。 P6PRODPF 记录在 SQL 清理 运行 后丢失。但是记住存储记录的进程运行同时。

我对 SQL 的理解是,它经过 P6PRODPF 并检查记录是否在 P6OPIPF 中,如果不在 P6OPIPF 中,则删除 P6PRODPF.

但后来我 运行 在我的系统导航器中对此 SQL 进行可视化解释并得到以下结果。

现在我很困惑。

在视觉解释之后 看起来语句以检查 P6OPIPF.

开头

然后它显示:如果在 P6OPIPF 中的那个时间实例中有记录,而在 P6PRODPF 中没有具有相同键的记录,则删除 P6PRODPF

这可以解释我的问题,即当我插入记录的进程和 sql 脚本同时运行时 P6PRODPF 被删除。

那么我在 Sequence 中是如何看待它的。(我的理论)

  1. 插入两条记录的过程开始。

  2. 插入两条记录的过程将第一条记录插入 P6OPIPF.

  3. 同时 SQL 清理运行。查询看到的是 P6OPIPF 记录并检查它是否有 P6PRODPF 记录。在这个阶段 仍然没有插入 P6PRODPF 所以 Sql 认为它需要 删除P6PRODPF.
  4. 中的记录
  5. 同时插入两条记录的进程插入了 P6PRODPF.
  6. 中的第二条记录
  7. 而且因为 Sql 在那个阶段没有看到 P6PRODPF 删除 P6PRODPF 中新插入的记录,留下 P6OPIPF 没有 P6PRODPF 记录的记录。

我说的对吗?

其实我想知道的只是上面列出的删除脚本。我对 SQL 的理解是,它通过 P6PRODPF 并检查记录是否在 P6OPIPF 中,如果不在 P6OPIPF 中,则删除 P6PRODPF。但是在视觉解释之后,我可以看到它是从检查 P6OPIPF 开始的。那么删除语句首先会检查什么?

插入代码在 CA PLEX 生成器中生成。 RPGIV 代码。

我的一个函数将首先插入 P6OPIPF(OperationsItem.Update.InsertRow),然后在 P6PRODPF(ProductDetail.Update.InsertRow).

中插入其详细信息

Insert Row function

将执行删除脚本的计划函数代码。

Scheduled delete script function

希望它有意义。

你听说过"transaction"和"isolation"这两个概念吗?通常针对同一数据库的不同进程 运行 相互屏蔽(隔离),因此它们在运行时不会同时看到任何其他事务 运行 的直接影响。从逻辑上讲,同时执行的两个事务(SQL 语句的过程或序列)以串行方式执行。

在您的情况下,第一个进程是 "first" 或 "second"。如果您重复测试,您可能会看到不同的结果,具体取决于谁是 "first"(逻辑上)。

Visual Explain 是了解数据库正在做什么的有用工具,尤其是在尝试提高性能时。

但是SQL不是过程语言。当我 运行 这个语句时,你不应该也不能真的试图说,数据库正在这样做,然后它正在这样做。

虽然对于特定 运行 可能是正确的,但它在很大程度上取决于可用的数据和资源。您不能围绕您看到的步骤编写流程。

您真的不应该尝试同时 运行 这两个过程,根本没有办法确保您最终会得到什么;至少在使用默认隔离级别时(可能 "no commit" 或 "read uncommited" 取决于接口。)

如果您必须运行同时处理两个进程,您可能希望运行删除"repeatable read"或"serializable"下的内容;这应该具有锁定被引用表的效果,以便其他进程无法更改它们。

您可以选择 运行 在读取稳定性或更高隔离级别下进行删除和插入。

为了解释 Visual Explain,DB2 将在执行 DELETE 子句之前检查内部表达式 - 它必须这样做,否则它不知道哪些行受到影响。

您的归档行未归档的原因是删除脚本 运行 在插入脚本之前。