【发布时间】:2010-12-27 21:06:29
【问题描述】:
那里有几个 ActiveRecord 样式的查询构建器库。有些是stand alone,有些是built into frameworks。但是,当涉及到复杂的 SQL 时,他们确实遇到了 WHERE 和 HAVING 子句的问题。将其他数据库放在一边——我正在尝试提出一种与 MySQL 和 PostgreSQL 兼容的 WHERE() 方法,该方法可以修复这些当前方法的缺陷。
接下来是一长串想法和示例,展示了我迄今为止所能想到的最好的方法。但是,我似乎无法解决所有用例,而且我觉得我的部分解决方案很草率。任何能够回答解决所有这些问题的东西的人不仅会回答这个问题,而且还要负责解决一个困扰 PHP 实现好几年的问题。
常用运算符
= Equal
<> Not Equal
> Greater Than
< Less Than
>= Greater Than Or Equal
<= Less Than Or Equal
BETWEEN between values on right
NOT logical NOT
AND logical AND
OR logical OR
示例 Where 子句
SELECT ... FROM table...
WHERE column = 5
WHERE column > 5
WHERE column IS NULL
WHERE column IN (1, 2, 3)
WHERE column NOT IN (1, 2, 3)
WHERE column IN (SELECT column FROM t2)
WHERE column IN (SELECT c3 FROM t2 WHERE c2 = table.column + 10)
WHERE column BETWEEN 32 AND 34
WHERE column BETWEEN (SELECT c3 FROM t2 WHERE c2 = table.column + 10) AND 100
WHERE EXISTS (SELECT column FROM t2 WHERE c2 > table.column)
where() 子句在不同的 current 库中使用了许多常见的 ActiveRecord 格式。
$this->db->where(array('session_id' => '?', 'username' => '?'));
$this->db->fetch(array($id, $username));
// vs with is_int($key)
$this->db->where(array('session_id', 'username'));
$this->db->fetch(array($id, $username));
// vs with is_string($where)
$this->db->where('session_id', '?');
$this->db->where('username');
$this->db->fetch(array($id, $username));
// vs with is_array($value)
$this->db->where('session_id', '?');
$this->db->where('username', array('Sam', 'Bob'));
$this->db->fetch(array($id));
这是我到目前为止的最终格式。它应该处理分组(...) AND (...) 以及准备好的语句绑定参数(“?”和“:名称”)。
function where($column, $op = '=', $value = '?', $group = FALSE){}
// Single line
$this->db->where('column > 5');
$this->db->where('column IS NULL');
// Column + condition
$this->db->where('column', '=');
// WHERE column = ? (prepared statement)
$this->db->where('column', '<>');
// WHERE column <> ? (prepared statement)
// Column + condition + values
$this->db->where('column', '=', 5);
// // WHERE column = 5
$this->db->where('column', 'IN', '(SELECT column FROM t2)');
// WHERE column IN (SELECT column FROM t2)
$this->db->where('column', 'IN', array(1,2,3));
// WHERE column IN (1, 2, 3)
$this->db->where('column', 'NOT IN', array(1,2,3));
// WHERE column NOT IN (1, 2, 3)
// column + condition + values + group
$this->db->where(
array(
array('column', '<', 20),
array('column', '>', 10)
),
NULL,
NULL,
$group = TRUE
);
// WHERE (column < 20 AND column > 10)
:更新:
在我提出问题的过程中,我开始意识到 WHERE 和 HAVING 条件只会越深入越复杂。尝试抽象 80% 的特征将导致一个庞大的库,仅用于 WHERE 和 HAVING。正如比尔指出的那样,这对于像 PHP 这样的脚本语言是不合理的。
解决方案就是手工制作查询的 WHERE 部分。只要您在列周围使用",您就可以在 Postgre、SQLite 和 MySQL 中使用相同的 WHERE 查询,因为它们使用几乎相同的 SQL 语法。 (对于 MySQL,您必须在 str_replace() 他们打勾`)。
有一点是抽象的伤害大于它的帮助,条件就是这样一个地方。
【问题讨论】:
标签: php sql mysql postgresql activerecord