【发布时间】:2013-04-17 10:12:17
【问题描述】:
我是 mysql 和 php 的新手,想澄清一下准备好的语句。
我看到的所有示例都只为表中的实际数据添加参数,将所有字段参数化以减少语句是不是不好的做法?例如
UPDATE ? SET ?=? WHERE ID=?
谢谢
【问题讨论】:
标签: php mysql prepared-statement
我是 mysql 和 php 的新手,想澄清一下准备好的语句。
我看到的所有示例都只为表中的实际数据添加参数,将所有字段参数化以减少语句是不是不好的做法?例如
UPDATE ? SET ?=? WHERE ID=?
谢谢
【问题讨论】:
标签: php mysql prepared-statement
你不能参数化标识符。您只能参数化数据。否则,参数化的重点,语句结构和数据之间的分离,是没有实际意义的。了解参数化不仅仅是花哨的复制和粘贴,它是一种确保数据库在 static 部分(它将从中获取指令)和 动态 部分(它将被视为数据和仅数据)。
就我个人而言,我真的不明白为什么每个人都试图尽可能减少 SQL 并且不想写任何东西。在现实世界的应用程序中,有一个定义的、有限的个应用程序将发送到数据库的 SQL 查询。将有一个查询来通过用户名查找用户,一个来计算条形表中 foo 的数量等。等等。写这些查询一次,长手。在某处有一个方法findUserByName(),其中包含查询以通过SQL 写出的名称查找用户。您不需要动态地将每个查询拼凑在一起,只需编写一次。这也为您提供了所有可能的数据库交互的良好“清单”,并允许在必要时进行手动调整。 </rant>
所以,这是不可能的和误导。
【讨论】:
UPDATE 语句是固定的,就像其他查询一样。您的图书馆看起来确实不错,而且肯定是一个好帮手。虽然老实说,我更相信数据库级别的参数化查询...... :)
$model->save(); 确实更容易。但是这种方法要么很难以快速回答 SO 的形式来证明(这就是为什么没有人在此类问题中宣传 ORM,恕我直言),而且并不总是可用。有时您必须只运行插入查询而不创建模型。当然,即使是 ORM 内部也可以从这样的辅助函数中受益。
虽然优秀的 deceze 的回答从字面上涵盖了您的问题,但还有其他要提的。
如果你看一下任何主要的框架,你会发现一个函数... update() 它的工作方式几乎相同:
function update($table, $data, $id) {
所以,这种方法总体上很受欢迎。
然而,这是错误的并且也是错误的。
最初不灵活,很快就变得无法使用:
所有这些情况都会使最初的小而整洁的功能变成臃肿的怪物。
但补救措施很简单。
您真正需要的是占位符,用于可能添加到查询中的每种数据类型。所以,欢迎来到SafeMysql - 一个实现你梦想的图书馆:
$db->query("UPDATE ?n SET ?u WHERE id=?i", $table, $data, $id);
它正在做你想做的事,但以正确的方式去做。即便如此复杂的查询也不会造成任何麻烦:
$data = array('field'=>$value,'field2'=>$value);
$ids = array(1,2,4);
$sql = "UPDATE t SET ts=unix_timestamp(), ip=inet_aton(?s),?u WHERE id IN(?a)";
$db->query($sql, $ip, $data, $ids);
虽然它的目的不是创建"less [SQL] statements",而是编写更少的 PHP 代码并使您的查询安全,同时保持它熟悉的常规 SQL,而不需要像学习某些查询的新语言这样的权衡Builder,它只是一种用 PHP 编写的 SQL 方言。
【讨论】:
是的,显然是因为它不可读。即使有值,我也认为最好以键形式使用占位符。例如
UPDATE mytable SET `name`=:fullname WHERE ID=:id
【讨论】: