使用绑定变量动态传递表名和列名

时间:2012-03-15 16:26:49

标签: sql oracle plsql oracle11gr2

有没有办法使用绑定变量动态地将列名和表名传递给查询?这可以通过使用简单的连接运算符||来完成,但我想要一种不同的方法来实现这一点。

编辑

OPEN abc_cur FOR 'Select :column_name
                  from :table_name' 
                USING column_name,table_name;

在此示例中,我将column_name传递为empno,ename,将table_name传递为emp

但这种做法对我不起作用。除了传统的连接方法之外,是否有可能采用不同的方法?

3 个答案:

答案 0 :(得分:14)

表和列名称不能作为绑定变量传递,否。绑定变量的重点是Oracle可以为语句生成一次查询计划,然后使用不同的绑定变量值多次执行它。如果优化器不知道正在访问哪个表或者正在选择和筛选哪些列,则无法生成查询计划。

如果您的担忧与SQL注入攻击有关,并且假设实际上需要动态SQL(大多数情况下,需要求助于动态SQL意味着数据模型存在问题),您可以使用DBMS_ASSERT package验证表名和列名不包含嵌入式SQL。

答案 1 :(得分:4)

不,你不能。更改查询中的表名或列名会更改该查询的语义 - 即它变为不同的查询。

绑定变量都是关于将不同的值传递给相同的查询。优化器可以使用不同的值重用查询,而无需重新解析并优化它。

答案 2 :(得分:0)

当我不得不根据 <select> 元素的值更改查询中的表时,我遇到了类似的问题。在这里的大多数答案中都说表名不能作为绑定变量传递,但是当我创建一个包含表名并传递给我的 sql 查询的变量时,它实际上有效:

<?php

$conn = mysqli_connect("<host>", "<username>", "<password>", "<database>");

$variable = "table_name";
$sql = $conn->("SELECT <column_name> FROM $variable ....);

?>

所以我所做的是我创建了一个函数并在我的函数中编写了我所有的 sql 查询。对于函数参数,我传递了名为 $table 的变量:

function getResult($table){
    
$conn = mysqli_connect("<host>", "<username>", "<password>", "<database>");
    $minDate = $conn->real_escape_string($_POST['minDate']);
    $maxDate = $conn->real_escape_string($_POST['maxDate']);
    $jobName = $conn->real_escape_string($_POST['jobName']);



$sql = $conn->query("SELECT COUNT(countX) as boxCount FROM $table WHERE job_name='$jobName' AND dateX BETWEEN '$minDate' AND '$maxDate'");


/* ... I removed the other operations from the code to make it compact */

然后我编写了根据作业名称的值更改目标表的条件:

if ($_POST['jobName'] === "job1"){
    getResult("table_name");
}
else if($_POST['jobName'] === "job2") {
    getResult("table_name");
}