【问题标题】:Select after insert doesn't return the inserted row插入后选择不返回插入的行
【发布时间】:2018-01-04 08:55:20
【问题描述】:

背景信息:我在一个管理文件的应用程序(专业,而非个人)上工作。 UI 是基于 Web 的,底层文件管理功能是基于 Java 的。

每个文件和目录在这个应用程序中都被称为一个“节点”,并且在一个表中有一行存储其 inode、名称、父 ID 等...

问题:当我们执行添加节点或重命名等操作时,会调用 java 函数来更新与真实文件系统相关的数据库。

只有当我们复制一个节点时我才会遇到问题(当我们添加、重命名、删除......一个节点时,即使调用与复制相同的 java 函数,一切都可以正常工作)==> 文件是复制,然后调用 java 函数(在这种情况下,它执行新文件信息的 SQL 插入),最后我在 PHP 中进行选择以获取复制文件的节点 ID。

插入后我可以在 PhpMyAdmin 中看到该行,但 PHP 中的选择不返回它。

我尝试过的: 这不是时间问题(我已将 20 秒睡眠时间用于测试并有时间查看 PMA 中的行)并且 CodeIgniter 中禁用了所有缓存(并且我在 CodeIgniter 代码中放置了各种转储来确认)。我也试过CodeIgniter的PDO驱动,结果完全一样。我尝试删除 where 子句(以及 where 子句)中的一些条件,结果还是一样。

唯一可行的方法是打开与数据库的新连接并重新执行查询,如下面的代码所示:

public function getIdForNode($name, $parentId) {
    $id = 0;
    $name = self::cleanName($name);
    $parentId = intval($parentId);
    if (empty($name)) {
        Log::error("\$name can't be empty.");
    } else if ($parentId < 0) {
        Log::error("\$parentId can't be < 0.");
    } else {
        $db = AppDatabase::getInstance();
        $sql = "SELECT node_ID
                FROM nodes
                WHERE inode_id > 0
                    AND parentNode_ID = ?
                    AND record_label = BINARY ?
                    AND record_deleted IS NULL";
        $result = $db->query($sql, [$parentId, $name])->row_array();
        ///////////////////////////////////////////////////////////////////
        if (empty($result)) {
            $db2 = new mysqli(DB_HOST, DB_USER, DB_PASS, DB_NAME);
            $result2 = $db2->query("
                SELECT node_ID
                FROM nodes
                WHERE inode_id > 0
                    AND parentNode_ID = ".$parentId."
                    AND record_label = BINARY '".$db2->escape_string($name)."'
                    AND record_deleted IS NULL
            ");
            $result = $result2->fetch_assoc();
            $result2->free();
            $db2->close();
        }
        ///////////////////////////////////////////////////////////////////
        $id = (!empty($result) && !empty($result['node_ID'])) ? intval($result['node_ID']) : 0;
    }
    return $id;
}

MySQL 5.5
PHP 5.5
CodeIgniter 3

如果您需要任何其他信息,请告诉我。

【问题讨论】:

  • 确保 $db 是数据库的实例。 (var_dump 来检查实例值。如果您没有得到任何结果,则运行任何简单的选择查询,那么 db 实例中存在错误。或者如果您在 codeigniter 的模型/控制器中,那么我猜一个将使用全局 db 对象 $this- >db->->query('params')
  • 我确定它是正确的数据库对象,因为我已经转储了它,我还在数据库驱动程序本身中放入了转储,一切正常;如果我删除 where 条件,我确实会得到结果(是的,条件是正确的,如果我在 PMA 中执行相同的查询,我会得到该行)。
  • 您未能检查某些地方的错误,尤其是对$db2-&gt;query() 的调用。如果不检查错误,您将永远不知道何时有错误。
  • 你为什么使用两个不同的连接$db和$db2?我假设,当您插入超过 $db2 时,来自 $db 的信息不会更新。

标签: php mysql mysqli codeigniter-3


【解决方案1】:

1) Mysqli 有一个方法用来获取最后一个插入 id。这将允许您简单地使用该值而无需选择。

http://php.net/manual/en/mysqli.insert-id.php

2) 打开mysql调试,看它运行一次。你可能会找到你的解决方案。

3) 我根本看不到 INSERT,因此插入 ... 之后的 SELECT 语句不是我可以解决的问题(因为它只发生在特定类型的插入上)。

最后,您需要了解为什么此 SELECT 和另一个 SELECT 之间存在差异,并且您已经将它与前面的 INSERT 语句相关联。但是您没有提供 INSERT 语句,也没有显示此选择与该插入的关系与其他插入的区别。

因此,您需要打开 mysql 调试并在它们运行时获取每个语句,以查看是否可以在 java/php 代码之外复制问题。也许您只是遇到了一种情况,即 java 代码执行无序(在 AJAX 中经常发生),或者在 select 执行之前还没有从技术上完成插入。到过那里。 ;)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-07-31
    • 1970-01-01
    • 2013-10-10
    • 1970-01-01
    • 1970-01-01
    • 2014-10-01
    相关资源
    最近更新 更多