gpt4 book ai didi

php - 事件记录 WHERE 子句中的额外连接词 : Where are they coming from?

转载 作者:行者123 更新时间:2023-11-29 23:29:36 26 4
gpt4 key购买 nike

当我正在使用的 CodeIgniter 应用程序尝试特定的 UPDATE 操作时,我收到一个非常奇怪的数据库错误。

Active Record 调用是:

$this->db->update('eval_events',
array('eval_event_totalscore'=>$result['average_score'],
'eval_event_average_totalscore=>$result['average_score']),
array('eval_event_id'=>$eval_event_id));

报告的错误是:

Error Number: 1054

Unknown column 'id' in 'where clause'

UPDATE `eval_events` SET `eval_event_totalscore` = '40.0000', `eval_event_average_totalscore`
= '40.0000' WHERE `id` = '581' AND `id` = '581' AND `id` = '581' AND `id` = '581' AND `id` =
'581' AND `id` = '581' AND `id` = '581' AND `id` = '581' AND `id` = '581' AND `id` = '581' AND
`id` = '581' AND `id` = '581' AND `id` = '581' AND `id` = '581' AND `id` = '581' AND `id` = '581'
AND `eval_event_id` = '565'

嗯?那些涉及“id”的额外连词到底是从哪里来的?

显然我没有通过它们,而我对 CI_active_record.php 的阅读没有给我任何线索。

另外三条可能相关的信息:

  1. 据我所知,此故障仅发生在我的开发计算机上。该查询在生产机器上似乎没问题。
  2. 如果我注释掉对 update() 的调用,以下调用update()以完全相同的方式被损坏。
  3. 值“581”在这些更新所属的操作的整体上下文中很重要,但它是不同表中的键(无论如何,它绑定(bind)到名为`pid`的列 ,而不是“id”)。

感觉就像 Active Record 代码已经缓存了 `id` = '581',并且此时有些东西导致它将该缓存的内容咳出到我的 UPDATE 语句中。

我承认我不明白Active Record的start_cache()是什么/stop_cache()/flush_cache()方法确实应该有益于——但这并不重要,因为 grep -r告诉我没有调用 start_cache()应用程序代码库中的任何位置。

只是为了笑,我尝试调用 $this->db->flush_cache()就在失败之前 update()调用,但没有改变任何东西。

我不知道接下来该去哪里寻找答案。

有什么想法吗?有人吗?

最佳答案

好的:echovar_export()debug_print_backtrace() 来救援。

事实证明,在 update() 调用失败的函数之前,有一个函数总共被调用了 16 次。 16 恰好是错误 UPDATE 语句中额外的 `id` = '581' 连接数。

在那个早期的函数中有以下代码(顺便说一句,我没有写任何这些垃圾):

$this->db->where('id',$pid);  // <=== WTF???
$sql = "SELECT id FROM project_score WHERE pid=$pid AND uid=$uid AND scoretype=1";
$result = $this->db->query($sql)->row_array();

这张照片有什么问题吗?

嗯,除了使用 Active Record 的可疑选择之外,* Active Record query() 方法不使用之前存储的任何内容调用 where()

因此,包含 16 个虚假条件的队列仍然悬而未决,等待将其自身附加到第一个毫无戒心的 update() (或 select() 等)电话随之而来。

为什么生产系统上不会发生这种情况?

嗯,在我的开发系统上,我暂时注释掉了一些其他(我并不真正关心的内容),这些内容由于本地 PHP 中缺少一些配置而失败 - 我没有这样做那时不想重建。

显然,我注释掉的内容都包含一个 Active Record 调用,该调用将 16 个条件的队列强加在其上 - 但它们碰巧对于该特定调用是良性的。

谢啦!

*那么这个“Active Record” mock 是谁的主意呢?

使用像 where() 这样的函数在全局对象上对事物进行排队是个好主意吗?难道不是更好的设计是让每个 SQL 语句成为一个不同的对象,这样构建一个 SQL 语句时所犯的错误就不会破坏应用程序完全不同部分中的另一个对象吗?

关于php - 事件记录 WHERE 子句中的额外连接词 : Where are they coming from?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26660994/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com