SQLSTATE [HY093]:参数号无效

时间:2014-03-06 10:54:26

标签: atk4

这个查询给我带来了很多麻烦:

/* Looking for a machine already attributed to a site:
       *      - Date_started is in the given period
       *  OR  - Date_ended is in the giver period
       *  OR  - Date_started is before the period's end AND date_ended is null
       *  AND - Que l'on parle de la même machine
       */                     
$dsql = $tmp->_dsql();
$machine = $tmp->selectQuery(array('site'))
           ->where($dsql->andExpr()
             ->where($dsql->orExpr()
               ->where('date_started BETWEEN "'
                         .$dsql->escape($this['date_started']).
                       '" AND "'
                         .$dsql->escape($this['date_ended']).
                       '"') 
               ->where('date_ended BETWEEN "'
                         .$dsql->escape($this['date_started']).
                       '" AND "'
                         .$dsql->escape($this['date_ended']).
                       '"')
               ->where($tmp->_dsql()->andExpr()
                 ->where('date_started < "'.$dsql->escape($this['date_ended']).'"')
                 ->where('date_ended IS null')
               )
             )
             ->where('machine_id = '.$dsql->escape($this['machine_id']))
             ->where('id != '.$dsql->escape($this['id']))
           )
           ->getOne();

许多问题首先是由括号引起的,这就是orExprandExpr这么多的原因。然后因为BETWEEN阻止使用转义值的地方($ field,$ cond,$ value)。

如果我没有逃避价值观,它会起作用,但像往常一样,我不应该信任数据。我知道我可以用$ dsql-&gt; expr()然后setCustom写下完整的查询,但这不是使用这么棒的框架的重点。

编辑:

Additional information:

pdo_error: SQLSTATE[HY093]: Invalid parameter number: no parameters were bound
mode: select
params:
query: select (select concat(`site`.`emplacement`, " (", (select `nom` from `region` where `site`.`region_id` = `region`.`id` ), ")") `designation` from `site` where `site_machine`.`site_id` = `site`.`id` ) `site`,`id`,`machine_id`,`site_id` from `site_machine` where ((date_started BETWEEN ":a" AND ":a_2" or date_ended BETWEEN ":a_3" AND ":a_4" or (date_started < ":a_5" and date_ended IS null)) and machine_id = :a_6 and id != :a_7)

1 个答案:

答案 0 :(得分:0)

您可以略微简化条件。 这应该与您在问题中写的相同:

date_started < period_end
AND (date_ended is null OR date_ended >= period_start)

是的,也没有更多的BETWEEN问题:)

如果您没有大量数据,那么您甚至可以这样做并完全摆脱OR。但请记住,ifnull(date_ended)不会使用索引,可能会更慢(检查SELECT的执行计划):

date_started < period_end
AND IFNULL(date_ended, period_start) >= period_start