带有子查询的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

PHP do/while Prepared Statement 失败

php mysql加入带有字段名的子数组