8

我面临一个小问题。我目前正在开发一个需要在 MySQL 中使用动态表名的应用程序。

基本上,我有一个基于多种因素(类型、播放长度、发行日期等)从数据库中选择专辑的过程——这个过程的一部分允许用户创建一堆自定义过滤器。

自定义过滤器向用户返回该选择条件内所有专辑的计数。然后将这些专辑的 ID 存储在一个带有随机生成的哈希/序列号的表中(例如,albumSelect_20880f9c05d68a)

我这样做是因为我不想在一个字段中存储一个巨大的逗号分隔列表(真的很傻)——而且我不喜欢将一组值发送到我的 HTML 中的隐藏字段,因为这只会增加数据吞吐量(一次可能是数千行)

在 CodeIgniter 中,我使用查询绑定来生成我的 SQL 查询,如下所示:

select * from artists where artistName = ? AND albumTitle = ?

当我参数化查询时,查询会自动转义

$query = $this->db->query($sql,array("Singer","Album"));

现在是棘手的部分

如果我将查询编写为如下所示:

$sql = "select albumid from albums where albumid in (select albumid from albumSelect_?)";
$this->db->query($sql,array('20880f9c05d68a'));

结果查询变为:

select `albumid` from `albums` where `albumid` in (select `albumid` from `albumSelect_'20880f9c05d68a'`)

完全正确,但显然查询无效..

编辑:更多信息

查询可能是更大查询的一部分,具体取决于用户选择的条件。例如

$sql = "select albumid from albums where albumid in(select albumid from tags where tag = ?) AND albumid in(select albumid from albumSelect_?)";

我只是想知道是否有办法让这个工作,或者是否有人可以提出更好的选择。表名的连接显然不是一个选项。

提前致谢!

戴夫

4

2 回答 2

1

转义机制仅适用于数据字符串,不适用于模式名称。换句话说,只针对表格的内容,不针对其结构。因此,您要么必须自己将字符串粘贴到查询中,要么避免以这种方式使用表。查询模板在?那里帮不上忙。

如果将字符串粘贴到表名中,则可以使用通常的 PHP 字符串连接机制。您应该额外确保对照适当严格的正则表达式检查字符串,以避免 SQL 注入。确保您实际上只粘贴您生成的格式的单个随机字符串,而不是其他任何内容。

作为替代方案,您可以有一个包含所有选择的大表,并使用附加列来保存您的标识散列,或使用其他合适的键来标识单个选择。这样,您就不必在正常操作期间修改数据库模式。我相信大多数开发人员,包括我在内,都宁愿避免通过程序代码进行此类修改。良好的数据库设计适用于固定模式。

于 2012-07-18T20:03:17.750 回答
0

听起来你想使用动态 SQL。您可能不得不走准备好的陈述的道路。有了它们,您可以调用PREPARE字符串,然后调用EXECUTE它。正常的连接工作得很好。

这应该允许您将 SQL 构建为字符串并执行它。如果将 CodeIgniter 的参数化与 MySQL 存储过程结合使用,则可以调用类似的查询"CALL selectAlbums(?, ?)"(假设selectAlbums是包含实际查询的存储过程PREPARE),它将返回集合。

如果您想摆脱'输出中的 s,请通过 引导参数CONCAT,这将产生一个正常的字符串。

于 2012-07-18T07:28:50.847 回答