MYSQL意外插入多行

Posted

技术标签:

【中文标题】MYSQL意外插入多行【英文标题】:MYSQL inserting multiple rows unexpectedly 【发布时间】:2015-08-12 00:42:18 【问题描述】:

我遇到了一个问题,希望有人可以帮助我。

我的问题是,每当我在“MainFile”中运行代码时,它会输出添加条目的两个 ID,但是当我查看我的数据库时,我有 六个 条目两个...谁能告诉我为什么会这样?

注意:我只提供了类中代码的 sn-ps,因为提供完整类的代码太多了。这是唯一被执行的代码。

编辑历史中的代码

编辑:我在这篇文章的底部添加了一个调试日志,以验证我只为每个查询执行一次 SQL 代码。

编辑:我不再使用序列化方法,因为存储这种类型的数据显然是个坏主意。然而,即使我的新代码将每个单独的值存储在数据库中,我仍然得到三个条目而不是一个。所以,这是同一个问题。有什么事吗?

编辑:经过几天的调试,我已将其范围缩小到导致问题的这一行

Throwlite::$systemSQL->executeSql("INSERT into ".SQL_COMMENTTHREADS_TABLE." (id, sort_order) values (DEFAULT, '2')");

您可以在此处查看 LiteSQL 类以供参考:http://pastebin.com/a4C6fF4u

另外,作为参考,这里是用于创建表的代码:

"CREATE TABLE IF NOT EXISTS `" . SQL_COMMENTTHREADS_TABLE . "` (`id` int unsigned NOT NULL AUTO_INCREMENT, `sort_order` int NOT NULL, PRIMARY KEY (`id`)) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ;"

而且,尽管我很确定这无关紧要,但这里是定义 SQL_COMMENTTHREADS_TABLE 的地方。

define( 'SQL_COMMENTTHREADS_TABLE', "tl_comment_threads");

【问题讨论】:

@shA.t 应该很明显它是 php,但我添加了标签以防万一。有什么帮助吗? 我认为您的问题不在于 mysql 行为,而在于您的 PHP 代码,我无法为您提供帮助;)。 数据库中的触发器可能会导致此行为。 您使用 MySQL 集群版本吗?我曾经在本地安装的集群版本(用于测试目的的同一台机器上所有节点的集群版本)遇到过类似的问题。 顺便说一句,您在发布的 pastebin 的第 51 行缺少第二个 if(sizeof($binds) > 0) 没有关闭。 【参考方案1】:

当更新UPDATE tl_comments SET thread=? WHERE id = ? 和第二个?未被替换为有效的现有 id 而是保持为空,数据库找不到要更新的条目并插入新行。因此,创建另一个条目会导致您在每次查询时生成 2 行而不是仅生成 1 行。

这意味着GetLastInsertID() 功能无法正常工作。这可能是由一些原因引起的,但在 *** 上已经有很多关于这个问题的有用提示。

【讨论】:

今晚下班回家后我会检查一下。但是,我很确定我已经验证了我使用 GetLastInsertID() 提取了正确的 ID。今晚我回家后通知你。 经过研究,我已经验证 GetLastInsertId() 方法工作正常。这是完整的 LiteSQL 类的副本:pastebin.com/a4C6fF4u 它在主文件中通过 ThrowLite::$systemSQL = new LiteSQL(); 进行初始化; Raphael,你确定 LiteSql 如果不能进行 UPDATE 就进行 INSERT 吗? (谢谢,thefiscster510)。 尝试在UPDATE OR IGNORE ... INSERT OR IGNORE ...中添加OR IGNORE 有很好的解释here【参考方案2】:

我不确定这是否能回答您的问题,但您似乎在指定要插入的 ID。我不确定您是否没有在 id 列上使用 PRIMARY KEY 或者为什么这完全有效,但也许您想要这个:

INSERT INTO " . SQL_COMMENTS_TABLE . " (id, thread) VALUES (DEFAULT, ?)

【讨论】:

另外,为什么你指定 ID 是一个字符串(带有“ss”),而它似乎是一个数字?如果您使用 GetLastInsertID,我假设这些行具有 AUTO_INCREMENT 老实说,就“SS”部分而言,当我这样做时我并没有考虑,但我没有遇到任何问题。不过我应该改变它,现在它已经引起了我的注意,一旦我下班回家,我就会这样做。就 PRIMARY KEY 而言,我确实将 ID 设置为主键。今晚我将尝试更多的事情,包括你提出的解决方案,我会告诉你进展如何。 我对上面的问题做了一些修改。我已经缩小了问题的根源,我只需要弄清楚问题到底是什么。如果您可以查看上面的问题以了解新的细节并参与进来,那就太棒了。谢谢。 我已经推送到项目的 GitHub 页面,您可以在其中查看项目中的所有代码。请注意,该项目基本上未完成。您一直在查看的代码可以在“classes/system/core/sql/litesql.class.php”和“classes/system/cmets/”下找到。在此测试中执行的唯一文件是位于项目根目录中的“tester.php”文件。 github.com/thefiscster510/ThrowLite 在另一个系统上运行它后,我意识到这与我的 WAMP 安装或配置有关。我尝试擦除我的 WAMP 安装并重新安装,但没有成功。有什么建议吗?【参考方案3】:

我在您提供的代码 sn-p 中找不到任何逻辑问题。 但是,您可以进行以下更改并在此处发布输出:

    为“prepared_statements”成员变量添加一个getter。 插入查询运行完成后,打印出上述 getter 函数的输出。

这个 DB 访问类的编写方式,很明显“prepared_statements”数组的单个索引中不可能存在两个插入查询。还是最好检查确认。 此外,如果您可以共享该函数(在该函数下运行插入查询代码段)并且调用该函数的代码 sn-p 对其他人调试问题很有用。

【讨论】:

我已经推送到项目的 GitHub 页面,您可以在其中查看项目中的所有代码。请注意,该项目基本上未完成。您一直在查看的代码可以在“classes/system/core/sql/litesql.class.php”和“classes/system/cmets/”下找到。在这个测试中执行的唯一文件是位于项目根目录中的“tester.php”文件。 github.com/thefiscster510/ThrowLite 在另一个系统上运行后,我意识到这与我的 WAMP 安装或配置有关。我尝试擦除我的 WAMP 安装并重新安装,但没有成功。有什么建议吗?【参考方案4】:

我觉得在您的代码中某处正在运行一个循环,导致在数据库中多次插入它。您可以尝试回显您的查询,以便您了解您的查询运行了多少次。

可以设置另一个 hack 条件来检查行是否已经存在 - 不要插入。

能否请您发布您的代码,以便我可以调试它。

【讨论】:

今晚下班回家时,我将推送到 GitHub 存储库,以便整个代码库可用。它相当大,但你可以筛选它。我已经发布了(在编辑历史以及问题本身中)我认为相关的所有代码。不过,我会在今晚发布其余的内容。 我已经推送到项目的 GitHub 页面,您可以在其中查看项目中的所有代码。请注意,该项目基本上未完成。您一直在查看的代码可以在“classes/system/core/sql/litesql.class.php”和“classes/system/cmets/”下找到。在这个测试中执行的唯一文件是位于项目根目录中的“tester.php”文件。 github.com/thefiscster510/ThrowLite 在另一个系统上运行后,我意识到这与我的 WAMP 安装或配置有关。我尝试擦除我的 WAMP 安装并重新安装,但没有成功。有什么建议吗? 我只是尝试卸载 WAMP 并安装 XAMPP,据我所知,这意味着它应该在完全干净的配置上运行。但是,我仍然遇到同样的问题,即插入了三个条目而不是一个。这对我来说完全没有意义,因为我在另外两台运行 WAMP 干净安装的机器上运行了完全相同的代码,它只插入了一个条目.. 在您的 /classes/system/cmets/core/cmetsystem.class.php 您正在使用 Throwlite::$systemSQL->executeSql("INSERT into ".SQL_COMMENTTHREADS_TABLE." (id, sort_order) 值(默认,'2')”);那么您在哪里定义了 $systemSQL 对象?你可以直接调用你的 executeSql 函数吗?你能试试也能打印你的绑定数组吗?【参考方案5】:

顺便说一句,您在发布的 pastebin 的第 51 行缺少第二个 if(sizeof($binds) > 0) 没有关闭。

【讨论】:

对此我感到非常抱歉,但在留下我的评论并再试几次后,我意识到问题仍然存在。但是,它显示了一个条目,然后我重新加载了 phpMyAdmin,而另外两个神奇地存在.. 对不起,我不能再用了。 我已经推送到项目的 GitHub 页面,您可以在其中查看项目中的所有代码。请注意,该项目基本上未完成。您一直在查看的代码可以在“classes/system/core/sql/litesql.class.php”和“classes/system/cmets/”下找到。在这个测试中执行的唯一文件是位于项目根目录中的“tester.php”文件。 github.com/thefiscster510/ThrowLite 在另一个系统上运行后,我意识到这与我的 WAMP 安装或配置有关。我尝试擦除我的 WAMP 安装并重新安装,但没有成功。有什么建议吗? 我只是尝试卸载 WAMP 并安装 XAMPP,据我所知,这意味着它应该在完全干净的配置上运行。但是,我仍然遇到同样的问题,即插入了三个条目而不是一个。这对我来说完全没有意义,因为我在另外两台运行 WAMP 干净安装的机器上运行了完全相同的代码,它只插入了一个条目..

以上是关于MYSQL意外插入多行的主要内容,如果未能解决你的问题,请参考以下文章

SyntaxError:JSON.parse:尝试插入 mysql 时 JSON 数据的第 1 行第 1 列出现意外字符

无法在 MySQL 语法错误中运行查询意外

如何在不引入意外空格的情况下在多行上编写 f 字符串? [复制]

mongodb启动服务时候报错。错误1067,进程意外终止。

插入/更新后跟选择(nolock)是不是会产生具有相同数据的意外结果?

查询的意外行为