PDO 无法在准备好的语句中使用整数来比较 mysql ENUM
我正在使用 PDO 和准备好的语句,但是当将 ENUM 字段与整数进行比较时,我似乎无法获得任何结果。
示例:
$db = new PDO('mysql:host=localhost;dbname=****', '***', '***');
$s = $db->prepare('SELECT id FROM t2 WHERE lang = ?');
$s->execute(array('en')); // Works
print_r($s->fetchAll());
$s->execute(array(2)); // Does not work
print_r($s->fetchAll());
我正在针对此表进行测试:
DROP TABLE IF EXISTS t2;
CREATE TABLE t2 (
id int(10) NOT NULL AUTO_INCREMENT,
lang enum('no','en','fr') NOT NULL,
PRIMARY KEY (id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
INSERT INTO t2 (id, lang) VALUES (NULL , 'en');
关于如何使其发挥作用有什么想法吗?
我正在转换为 PDO,并且我不想重写应用程序中的所有常量、枚举和查询:(
I am using PDO and prepared statements, but i cannot seem to get any results when comparing an ENUM field with an integer.
Example:
$db = new PDO('mysql:host=localhost;dbname=****', '***', '***');
$s = $db->prepare('SELECT id FROM t2 WHERE lang = ?');
$s->execute(array('en')); // Works
print_r($s->fetchAll());
$s->execute(array(2)); // Does not work
print_r($s->fetchAll());
I Am testing against this table:
DROP TABLE IF EXISTS t2;
CREATE TABLE t2 (
id int(10) NOT NULL AUTO_INCREMENT,
lang enum('no','en','fr') NOT NULL,
PRIMARY KEY (id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
INSERT INTO t2 (id, lang) VALUES (NULL , 'en');
Any idea on how to get this to work?
I am converting to PDO, and I'd prefer not to rewrite all constants, enums, and queries in my app :(
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
2
不是有效的 ENUM 元素。就这么简单。当您执行
lang = 2
时,它在原始 MySQL 中工作的原因是,它公开了列表的底层存储机制(基本上它只是一个标准化值,但标准化通过 ENUM 对您隐藏)柱子)。我建议不要尝试这样做。 MySQL 隐藏实现是有原因的。意识到使用
2
进行比较只不过是一个 魔法数字...2
is not a valid ENUM element. It's as simple as that.The reason it works in raw MySQL when you do
lang = 2
, is that it's exposing the underlying storage mechanism for the list (basically it's just a normalized value, but the normalization is hid from you by the ENUM column).I'd suggest not trying to do this. MySQL hides the implementation for a reason. Realize that using
2
for the comparison is nothing more than a magic number...语言不应该是枚举,事实上根本不使用枚举而是使用单独的查找/类型表:
您还应该意识到向 ENUM 定义添加新值将需要MySQL 重建整个表 – 对于大型表来说不是最佳的!!
language shouldn't be an enum, infact don't use enums at all instead use separate lookup/type tables:
you should also be aware that adding a new value to the ENUM definition will require MySQL to rebuild the entire table – less than optimal for large tables !!
推理:
我同意您不必通过枚举索引选择任何内容,甚至根本不必使用数据库枚举,但总有例外和特殊情况。
就我而言,它是一个遗留系统,当然意味着要被新系统取代,但这至少需要一年,甚至可能更长。
对遗留系统的任何数据库更改都会产生很大的影响,我们尽力将其保持在最低限度。我们确实有一个包含用户组的小表,并且组 ID 也设置为枚举。所以是的,添加组还需要向该表的 id 列添加另一个枚举值。
我确实不知道这是怎么发生的,我也不会质疑它,我只是必须处理它,直到我们可以完全取代它。
我想提供一个简单的用户管理,因为现在任何用户更改都必须经过一个漫长的过程,这导致开发人员直接在数据库中进行更改。用户组按枚举索引分层,我想过滤管理中的可用组,使其小于或等于当前登录的用户组。
长话短说;为了在准备好的声明中完成这项工作,我这样做了:
说明:
通过向列添加
+0
,MySQL 会自动将该列视为整数,并使用枚举索引而不是值。这是一个简单的技巧,可能会导致其他问题,但到目前为止我还没有遇到任何问题。Reasoning:
I agree that you should not have to select anything by enum index or even use database enums at all, but there are always exceptions and special cases.
In my case, it's a legacy system that is of course meant to be replaced by a new system, but that will take at least one year, possibly way longer.
Any database changes to the legacy system have a large impact and we try to keep them at a minimum. We do have a small table with users groups, and the group ids are also set as enums. So yes, adding a group does also require adding another enum value to that table's id column.
I do have no knowledge about how this came to be and I don't question it, I just have to deal with it until we can completely replace it.
I want to provide a simple user administration since any user changes right now have to go through a long process which results in a developer doing the changes directly in the database. The user groups are hierarchical by enum index and I wanted to filter the available groups in the administration to be less than or equal to the currently logged-in users group.
Long story short; To make this work in a prepared statement, I did this:
Explanation:
By adding
+0
to the column, MySQL automatically treats the column as an integer and uses the enum index instead of the value. It's a simple trick that may cause other problems, but I didn't encounter any so far.