我试图让用户在php和oracle中选择他们想要从数据库中排序结果的顺序。 我有一个绑定工作在where子句,但我不能使它与order by子句一起工作。 有没有办法按语句绑定订单?
我在docs中找不到任何内容。
示例代码:
<?php
$db = ...
$sql = "SELECT * FROM TABLE WHERE val1 = :val1 ORDER BY :orderBy";
$id = oci_parse($db, $sql);
// this works
$val = "test";
if (oci_bind_by_name($id, ":val1", $val)) {
echo 'bound where clause';
}
// this doesn't
$orderBy = "val1";
if (oci_bind_by_name($id, ":orderBy", $orderBy)) {
echo 'bound order by clause';
}
?>
答案 0 :(得分:3)
这是一种使用绑定变量来改变ORDER BY
:
<?php
$conn = oci_connect('hr', 'welcome', 'localhost/orclpdb');
$query = "select first_name, last_name
from employees
order by
case :ob
when 'FIRST_NAME' then first_name
else last_name
end";
$vs = "FIRST_NAME";
$s = oci_parse($conn, $query);
oci_bind_by_name($s, ":ob", $vs);
$r = oci_execute($s);
echo "<table border='1'>\n";
while (($row = oci_fetch_array($s, OCI_ASSOC+OCI_RETURN_NULLS)) != false) {
echo "<tr>\n";
foreach ($row as $item) {
echo " <td>".($item !== null ? htmlentities($item, ENT_QUOTES):" ")."</td>\n";
}
echo "</tr>\n";
}
答案 1 :(得分:1)
不,你不能。 Oracle SQL处理经历一个初始的解析阶段,然后是一个或多个绑定和获取阶段(对于整个结果集,提取可以是部分或完成的)。
执行计划在解析时得到修复,因此绑定新变量不会改变执行计划。如果初始选择是“SELECT NAME,DEPT,HIRE_DATE FROM EMP ORDER by HIRE_DATE”或“SELECT NAME,DEPT,HIRE_DATE FROM EMP ORDER BY 3”,执行计划可以选择在HIRE_DATE使用索引来获取请求订单而无需排序。
如果该声明成为“SELECT NAME,DEPT,HIRE_DATE FROM EMP ORDER BY 2”,那么执行计划将以错误的顺序返回结果。因此,必须单独解析该语句,并且在执行绑定阶段之前确定需要结果的顺序。