dtnwm4807 2012-07-06 18:47
浏览 149
已采纳

SQLSTATE [HY093]:参数号无效:混合命名和位置参数

This error to me seems a bug because there are no positional parameters in my query. Here is the method:

public function getAll(User $user, DateTime $start = null, DateTime $end = null)
{
    $params = array('user_id' => $user->getId());

    $rsm = new \Doctrine\ORM\Query\ResultSetMapping(); // Result set mapping
    $rsm->addScalarResult('subtype', 'subtype');
    $rsm->addScalarResult('count',   'count');

    $sms_sql =
    "SELECT CONCAT('sms_', IF(is_auto = 0, 'user' , 'auto')) AS subtype, " .
    "SUM(messages_count * (customers_count + recipients_count)) AS count " .
    "FROM outgoing_message AS m INNER JOIN small_text_message AS s ON " . 
    "m.id = s.id WHERE status <> 'pending' AND user_id = :user_id";

    $news_sql =
    "SELECT CONCAT('news_', IF(is_auto = 0, 'user' , 'auto')) AS subtype, " .
    "SUM(customers_count + recipients_count) AS count " .
    "FROM outgoing_message AS m JOIN newsletter AS n ON m.id = n.id " .
    "WHERE status <> 'pending' AND user_id = :user_id";

    if($start) :
        $sms_sql        .= " AND sent_at >= :start";
        $news_sql       .= " AND sent_at >= :start";
        $params['start'] = $start->format('Y-m-d');
    endif;

    $sms_sql  .= ' GROUP BY type, is_auto';
    $news_sql .= ' GROUP BY type, is_auto';

    return $this->_em->createNativeQuery("$sms_sql UNION ALL $news_sql", $rsm)
        >setParameters($params)->getResult();
}

And this throws the exception:

SQLSTATE[HY093]: Invalid parameter number: mixed named and positional parameters

Array $params is OK and so generated SQL:

var_dump($params);

array (size=2)
  'user_id' => int 1
  'start' => string '2012-01-01' (length=10)

The strangest thing is that it works with "$sms_sql" only!

Update

Found another strange thing. If I change only the name (to start_date instead of start):

    if($start) :
        $sms_sql             .= " AND sent_at >= :start_date";
        $news_sql            .= " AND sent_at >= :start_date";
        $params['start_date'] = $start->format('Y-m-d');
    endif;

What happens is that Doctrine/PDO says:

SQLSTATE[42S22]: Column not found: 1054 Unknown column 'sent1rt_date' in 'where clause'

... as string 1rt was added in the middle of the column name!

  • 写回答

1条回答 默认 最新

  • dtczp02204 2012-07-06 21:11
    关注

    I believe the problem is with the Doctrine ORM support for NativeSQL.

    I don't find any examples in the documentation of the setParameters method being used for named parameters. All of the examples I see of that method being used are for positional, rather than named.

    All of the examples for named parameters use the setParameter (with no "s") method. And they only show a single occurrence of a matching placeholder in the SQL.

    As a test (and as a possible workaround), try making each placeholder in the SQL text unique, and then set each one separately.

    It looks like "named parameter" support may be somewhat incomplete (compared to what we are used to with Oracle and other ORM frameworks). It looks like Doctrine may have better support for the positional notation. (Which is great for simple statements, but it can be a real bear when you have lots of parameters, and you need to make changes to a SQL statement. That's where the benefit of named parameters really begins to shine... if they are supported right.)

    Here's a link to the Doctrine ORM documentation http://doctrine-orm.readthedocs.org/en/latest/reference/query-builder.html?highlight=setParameters (Search for setParameters on that page for examples.)

    (See my comments on your question.)

    That may not really answer your question, but it may get you moving in the right direction. Be careful out there.

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 素材场景中光线烘焙后灯光失效
  • ¥15 请教一下各位,为什么我这个没有实现模拟点击
  • ¥15 执行 virtuoso 命令后,界面没有,cadence 启动不起来
  • ¥50 comfyui下连接animatediff节点生成视频质量非常差的原因
  • ¥20 有关区间dp的问题求解
  • ¥15 多电路系统共用电源的串扰问题
  • ¥15 slam rangenet++配置
  • ¥15 有没有研究水声通信方面的帮我改俩matlab代码
  • ¥15 ubuntu子系统密码忘记
  • ¥15 保护模式-系统加载-段寄存器