带有子查询的PHP Prepared Statement变量绑定错误
Posted
技术标签:
【中文标题】带有子查询的PHP Prepared Statement变量绑定错误【英文标题】:PHP Prepared Statement variable binding error with subquery 【发布时间】:2015-05-26 03:49:00 【问题描述】:我有一个像这样的子查询的查询
SELECT ...
FROM (SELECT ...
FROM ...
GROUP BY ...) as speedLimitCalc INNER JOIN
(SELECT ...
FROM date a INNER JOIN HOURLY_TEST b ON a.[FULL_DAY_DT] = b.DATE
WHERE (b.DATE BETWEEN '".$date_s."' AND '".$date_e."')
AND HOUR BETWEEN ".$time_s." AND ".$time_e."
AND(LKNO BETWEEN '".$lkno_s."' and '".$lkno_e."')
AND RDNO= '".$rdno."'
AND pub_hol IN (".$pubholquery.")
AND school_hol IN (".$schholquery.")
AND day_no IN (".$dayquery.")
GROUP BY RDNO, LKNO, PRESCRIBED_DIRECTION, CWAY_CODE) as origtable ON ...
,(SELECT ...
FROM [Dim_date]
WHERE (FULL_DAY_DT BETWEEN '".$date_s."' AND '".$date_e."')
AND pub_hol IN (".$pubholquery.")
AND school_hol IN (".$schholquery.")
AND day_no IN (".$dayquery.") ) as c
ORDER BY ...
我在内部查询 where 子句中插入变量。
我正在尝试使用 odbc_prepare 和 odbc_execute 对此查询进行参数化,但是我遇到了绑定变量的问题。目前,当我使用以下
$result = odbc_prepare($connection, $query);
odbc_execute($result)or die(odbc_error($connection));
运行这个查询,一切正常。但是,当我尝试绑定变量时,例如
AND RDNO= ?
...
odbc_execute($result, array($rdno))or die(odbc_error($connection));
我收到以下错误消息。
php 警告:odbc_execute() [/phpmanual/function.odbc-execute.html]:SQL 错误:[Microsoft][ODBC SQL Server Driver]参数号无效,SQLDescribeParameter 中的 SQL 状态 S1093
我的猜测是因为我在子查询中绑定了一个变量,因为当 Where 子句位于顶部 Select 查询中时,此过程有效。
我想知道以前是否有其他人遇到过这个问题,以及他们是如何解决的?谢谢
【问题讨论】:
【参考方案1】:通过使用临时表将查询分成多个查询来消除子查询中对参数的需求,从而解决了该问题。
$query = "SELECT ...
INTO ##avgspeedperlink
FROM Date a INNER JOIN HOURLY_TEST ON a.[FULL_DAY_DT] = b.DATE
WHERE (b.DATE BETWEEN ? AND ?)
AND HOUR BETWEEN ? AND ?
AND(LKNO BETWEEN ? and ?)
AND RDNO= ?
AND pub_hol IN (".$pubholquery.")
AND school_hol IN (".$schholquery.")
AND day_no IN (?,?,?,?,?,?,?)
GROUP BY RDNO, LKNO, PRESCRIBED_DIRECTION, CWAY_CODE";
$result = odbc_prepare($connection, $query);
odbc_execute($result, array($date_s,$date_e,$time_s,$time_e,$lkno_s,$lkno_e,$rdno,$daysanitised[0],$daysanitised[1],$daysanitised[2],$daysanitised[3],$daysanitised[4],$daysanitised[5],$daysanitised[6]))or die(odbc_error($connection));
$query = "SELECT ...
INTO ##daysinperiod
FROM [RISSxplr].[dbo].[Dim_date]
WHERE (FULL_DAY_DT BETWEEN ? AND ?)
AND pub_hol IN (".$pubholquery.")
AND school_hol IN (".$schholquery.")
AND day_no IN (?,?,?,?,?,?,?)";
$result = odbc_prepare($connection, $query);
odbc_execute($result, array($date_s,$date_e,$daysanitised[0],$daysanitised[1],$daysanitised[2],$daysanitised[3],$daysanitised[4],$daysanitised[5],$daysanitised[6]))or die(odbc_error($connection));
$query = "SELECT ...
FROM ##avgspeedperlink, ##daysinperiod
ORDER BY LKNO, OUTBOUND
drop table ##avgspeedperlink
drop table ##daysinperiod";
请注意,我必须使用双 ## 来制作临时表(单 # 表示该表是查询的本地表,## 表示该临时表对于多个查询来说是全局的)。
【讨论】:
以上是关于带有子查询的PHP Prepared Statement变量绑定错误的主要内容,如果未能解决你的问题,请参考以下文章
PHP PDO - 关闭语句 - 不能创建超过 max_prepared_stmt_count 语句
是否可以使用 PHP+ODBC 发送包含带有内部连接的子查询的查询?
PDO Prepared Statement 允许执行 javascript
PHP MySQLi Prepared Statements Tutorial to Prevent SQL Injection