代码中的动态 SQL 查询可能吗?

Posted

技术标签:

【中文标题】代码中的动态 SQL 查询可能吗?【英文标题】:Dynamic SQL queries in code possible? 【发布时间】:2011-01-16 05:47:16 【问题描述】:

除了像Select * from users where user_id =220202 这样的硬编码sql 查询之外,这些查询可以像Select * from $users where $user_id = $input. 这样动态化

我问的原因是,当需要更改表/列名称时,我可以在一个地方对其进行更新,而不必要求开发人员逐行查找所有要更新的引用。这非常耗时。而且我不喜欢在代码中公开数据库内容的想法。

我主要关心的是加载时间。与动态页面一样,数据库必须获取页面内容,同样如果查询是动态的,系统首先必须查找引用然后执行查询,所以它会影响加载时间吗?

我正在使用 codeignitor php

如果可能,那么下一个问题是在哪里存储所有引用?在应用程序中,在文件中,在数据库中,以及如何?

---编辑:更好的是:SQL 查询本身可以动态化吗?我可以只引用 $sqlA 而不是整个查询吗?这样,如果我必须重新编写查询,我可以只更新 1 个文件。

【问题讨论】:

【参考方案1】:

因为您使用的是 Codeigniter,我建议您使用 Active Record Class 来完成您想要做的事情。

活动记录类使您​​能够分步动态构建查询,从而使您能够以逻辑方式构建它们。因此,以使用活动记录为例...

(这可以用更少的代码来完成,我只是想说明 Active Record)

$this->db->select('*');

$this->db->from($table);

$this->db->where($user_id, $input);

为了说明我对逻辑构建查询的含义,您可以构建任何您想要的逻辑进入查询构建过程。假设您有一个 $limit 变量,如果您想限制获得的结果数量,您可以设置该变量。但是如果没有设置(或NULL),你不想设置限制子句。

if ( $isset($limit) ) 
    $this->db->limit($limit);

现在执行你的查询,因为它已经构建了

$query = $this->db->get();

然后就像处理任何其他 CodeIgniter 查询对象一样,用您的 database class 处理 $query

【讨论】:

【参考方案2】:

当然可以,如果你愿意的话。我宁愿建议您花更多时间来设计数据库,但从长远来看,架构的更改是不可避免的。

我认为加载时间不会成为问题,因为通常此应用程序的瓶颈在数据库中。

最后我的建议是通过将列名声明为 php 变量来将其保存在文件中

【讨论】:

一点更正:瓶颈通常不是数据库(这真的很快),而是建立连接并与数据库通信。【参考方案3】:

这取决于您使用的数据库驱动程序。旧的 PHP 数据库驱动程序不支持占位符 (PHP 3.x)。现代(PDO)的。你用问号写 SQL:

SELECT * FROM Users WHERE User_ID = ?

然后在执行查询时提供用户 ID 的值。

但是,您不能像这样提供列名 - 只能提供值。但是你可以从一个字符串中准备一个语句,例如:

SELECT * FROM Users WHERE $user_id = ?

然后你在执行时提供值。

【讨论】:

【参考方案4】:

mysql_query() 接受一个字符串,它不需要是一个常量字符串,它可以是一个变量。

$SQL = "SELECT foo FROM bar b";
SQLSet = mysql_query($SQL);

你可以看到,你可以使用普通的字符串操作来构建你的整个 SQL 查询。

$SQL="SELECT * FROM MyTable";
$BuzID = 5;
$Filter = "Buz=".$BuzID;
if (is_numeric($BuzID)) SQL .= " WHERE ".$Filter;
SQLSet = mysql_query($SQL);

如果 $BuzID 设置为任意数字,这将扩展为 "SELECT * FROM MyTable WHERE Buz=5"。 如果不是,则声明将只是 "SELECT * FROM MyTable"

如您所见,您可以即时构建非常复杂的 SQL 语句,而无需 SQL 服务器中的变量支持。

如果您想要数据库名称、用户登录等常量,您可以将它们放在公共目录之外的单独包含中。

SecretStuff.inc.php
$__DatabaseName = "localhost";
$__UserName = "DatabaseAccess";
$__Password = "E19A4F72B4AA091C6D2";

或者将整个 PHP 数据库连接代码放在同一个文件中。

【讨论】:

以上是关于代码中的动态 SQL 查询可能吗?的主要内容,如果未能解决你的问题,请参考以下文章

这种动态 SQL 查询生成对注入安全吗?

SQL Server如何防止动态sql中的sql注入

Linq2Sql - 存储复杂的Linq查询以便将来动态执行 - 原始文本 - 可能吗?

我可以从存储在 S3 中的 sql 文件运行 Athena 查询吗

使用dapper时动态拼接查询sql有啥好的方法吗

MyBatis动态SQL和缓存