提问人:mario 提问时间:9/13/2010 最后编辑:mario 更新时间:10/1/2010 访问量:4065
SQL 的扩展占位符,例如 WHERE id IN (??)
Extended placeholders for SQL, e.g. WHERE id IN (??)
问:
赏金更新:已经从马克那里得到了很好的答案。将 := 改编为 :,如下。但是,除了 DBIx 之外,我仍在寻找类似的方案。我只是对兼容任何东西感兴趣。
我需要关于我在参数化 SQL 语句中为“扩展”占位符选择的语法的建议。因为构建一些结构(IN子句)很困扰我,所以我决定使用一些语法快捷方式,这些快捷方式会自动扩展到普通?占位符。
我喜欢他们。但我想把它打包分发,并问自己它们是否容易理解。
基本上,我的新占位符是 and(枚举参数)和 and and and(对于命名占位符),用例如下:??
:?
:&
:,
:|
::
-> db(" SELECT * FROM all WHERE id IN (??) ", [$a, $b, $c, $d, $e])
根据对我的 db() 函数的$args数,扩展为。这个很清楚,它的语法已经有点标准化了。Perls DBIx::Simple 也使用它。所以我很确定这是一个可以接受的想法。??
?,?,?,?,?,...
-> db(" SELECT :? FROM any WHERE id>0 ", ["title", "frog", "id"]);
// Note: not actually parameterized attr, needs cleanup regex
承认吧。我只是喜欢笑脸。基本上,此占位符将关联$args扩展为普通列名称。事实上,它抛弃了任何$args值。它实际上对 INSERT 与 ??, 结合使用很有用,有时对 IN 子句也很有用。但在这里我已经想知道这种新语法是否合理,或者不仅仅是一个用词不当,因为它混合了 : 和 ?字符。但不知何故,它似乎与语法方案很好地匹配。:?
-> db(" UPDATE some SET :, WHERE :& AND (:|) ", $row, $keys, $or);
在这里,助记符扩展为用逗号分隔的对列表。而 the 是由 s 连接的 column=:column 列表。为了平价,我添加了.不过,:& 在 UPDATE 命令之外还有其他用例。
但我的问题不是关于有用性,而是 :, 和 :& 似乎可以记住吗?:,
name=:name
,
:&
AND
:|
-> db(" SELECT * FROM all WHERE name IN (::) ", $assoc);
经过一段时间后,我还添加了插值,非常喜欢扩展到 .类似的用例,并且具有均匀性是明智的。::
:named,:value,:list
??
?,?,?
无论如何,有没有人实施过这样的计划?不同的占位符?或者为了简单起见,您会推荐哪一个?更新:我知道PHP Oracle OCI接口也可以绑定数组参数,但不使用特定的占位符。我正在寻找可比较的占位符语法。
答:
非常整洁!我认为占位符很好,只要你很好地记录它们并在分发时提供大量示例。你发明了自己的占位符是可以的;毕竟,总得有人考虑用。?
您可能希望避免用作占位符,因为它已经在例如 MySQL 中具有用法。:=
例如,请参阅此答案以了解实际使用情况。
评论
:
:=
我喜欢你的提案背后的基本思想,但不喜欢占位符的“命名”。我基本上有两个反对意见:
- 占位符以 或 开头。您应该选择一种形式,以便可以立即识别占位符。我会选择它,因为它与 SQL 发生冲突的可能性较小,并且更常见于表示占位符。
:
?
?
- 占位符很难理解,也很难记住。 在我看来似乎是合理的,但区分,而且相当困难。
:&
:|
??
:?
:
我更改了我的数据库类以支持更多的占位符并更加智能:DB_intelligent.php(自述文件中关于占位符的部分不适用于此类。它仅适用于普通班级。
DB 类有两种类型的占位符:多功能占位符和关联数组占位符(可以是 或 )。?
?x
x
,
&
|
占
位符:此占位符根据参数的类型确定插入的类型:
null => 'NULL'
'string' => 'string'
array('foo', 'bar') => ('foo','bar')
?x
占位符:数组中的每个元素都转换为结构并用分隔符内爆。分隔符由组件指定:用逗号、by 和 by 分隔。`field`='value'
x
,
&
AND
|
OR
示例代码:
DB::x(
'UPDATE table SET ?, WHERE value IN ? AND ?&',
array('foo' => 'bar'),
array('foo', 'bar'),
array('hallo' => 'world', 'hi' => 'back')
);
// Results in this query:
// UPDATE table SET `foo`='bar' WHERE value IN ('foo','bar') AND `hallo`='world' AND `hi`='back'
在设计这个版本的 DB 类时,我有一些想法:
可能会出现一个明显的想法:为什么不用于所有类型的数据,甚至是关联数组。仅添加和添加。在关联数组上使用与在当前设计中使用相同。我没有这样做的原因是安全性。您经常希望将 中的数据插入到查询 () 中。但是,由于 HTML 允许数组 () 表单控件,因此也可以提交具有相同名称的关联数组。因此,我的查询合成器会将其识别为字段 => 值列表。尽管这可能不会损害安全性,但它会导致 SQL 错误,这是很糟糕的。?
?&
?|
?
?,
<select multiple>
IN ?
form[array]
评论
?
?*
:*
addslashes
self::$instance->quote
\'
''
如果你愿意花一些时间学习教义,那么你可以做一些令人惊奇的事情,比如:
$q = Doctrine_Query::create()
->select('u.id')
->from('User u')
->whereIn('u.id', array(1, 3, 4, 5));
echo $q->getSqlQuery();
什么会产生这样的查询:
SELECT
u.id AS u__id
FROM user u
WHERE u.id IN (?,
?,
?,
?)
此示例摘自:doctrine dql documentation
评论
GROUP BY
HAVING
ORDER BY