2014-08-29 3 views
0

У меня есть строка запроса MySQL с несколькими неназванного местоблюстителем (?), каждый прием тот же параметр:Что более лаконичный способ, чтобы связать один и тот же параметр, несколько раз, с помощью PDO

$sql = "SELECT DISTINCT A1.pagetitle, A1.content, A1.uri, A2.value, ". 
      "CASE ". 
       "WHEN A1.pagetitle LIKE ? THEN 1 ". 
       "WHEN A1.content LIKE ? THEN 2 ". 
       "WHEN A2.value LIKE ? THEN 3 ". 
      "END AS rank ". 
     "FROM mod_site_content A1 ". 
     "LEFT JOIN mod_site_tmplvar_contentvalues A2 ". 
      "ON A1.id = A2.contentid ". 
      "AND A2.tmplvarid IN(15,17) ". 
     "WHERE (pagetitle LIKE ? ". 
      "OR content LIKE ? ". 
      "OR value LIKE ?) ". 
     "ORDER BY rank"; 

$stmt = $db->prepare($sql); 
$searchq = "%".$searchq."%"; 

и в настоящее время я повторив привязки, в то, что кажется довольно многословным образом:

$stmt->bindParam(1, $searchq, PDO::PARAM_STR); 
$stmt->bindParam(2, $searchq, PDO::PARAM_STR); 
$stmt->bindParam(3, $searchq, PDO::PARAM_STR); 
...etc 

есть ли опрятнее и более ремонтопригоден способ связывания тот же параметра на любое количество заполнителей?

EDIT: PHP версии 5.10.1

ответ

1

Простой цикл будет делать.

foreach($i = 1; $i <= 3; ++$i) { 
    $stmt->bindParam($i, $searchq, PDO::PARAM_STR); 
} 

Или, если у вас есть некоторые показатели, которые будут пропущены:

foreach($i in range(1,3,4,7)) { 
    $stmt->bindParam($i, $searchq, PDO::PARAM_STR); 
} 
+0

Не работает для меня - я получаю 500 внутренних ошибок с этим. Возможно, вам нужно увидеть всю функцию? – verism

1

Как о написании запроса, как это?

SELECT DISTINCT A1.pagetitle, A1.content, A1.uri, A2.value, 
     (CASE WHEN A1.pagetitle LIKE vars.pattern THEN 1 
      WHEN A1.content LIKE vars.pattern THEN 2 
      WHEN A2.value LIKE vars.pattern THEN 3 
      . . . 
     ) as val 
FROM . . . CROSS JOIN 
    (SELECT ? as pattern) vars 
. . . 

Тогда вам нужно включить его только один раз.

EDIT:

Ваш запрос будет выглядеть следующим образом:

SELECT DISTINCT A1.pagetitle, A1.content, A1.uri, A2.value, 
     (CASE WHEN A1.pagetitle LIKE vars.pattern THEN 1 
      WHEN A1.content LIKE vars.pattern THEN 2 
      WHEN A2.value LIKE vars.pattern THEN 3 
     END) AS rank 
FROM mod_site_content A1 LEFT JOIN 
    mod_site_tmplvar_contentvalues A2 
    ON A1.id = A2.contentid AND A2.tmplvarid IN (15, 17) CROSS JOIN 
    (SELECT ? as pattern) vars 
WHERE (pagetitle LIKE vars.pattern OR content LIKE vars.pattern OR value LIKE vars.pattern); 
ORDER BY rank; 

Вы можете упростить это с помощью having:

SELECT DISTINCT A1.pagetitle, A1.content, A1.uri, A2.value, 
     (CASE WHEN A1.pagetitle LIKE vars.pattern THEN 1 
      WHEN A1.content LIKE vars.pattern THEN 2 
      WHEN A2.value LIKE vars.pattern THEN 3 
     END) AS rank 
FROM mod_site_content A1 LEFT JOIN 
    mod_site_tmplvar_contentvalues A2 
    ON A1.id = A2.contentid AND A2.tmplvarid IN (15, 17) CROSS JOIN 
    (SELECT ? as pattern) vars 
HAVING rank > 0 
ORDER BY rank; 

А потом, если "узоры" не используется подстановочные знаки, вы могли бы просто сделать:

SELECT DISTINCT A1.pagetitle, A1.content, A1.uri, A2.value, 
     field(vars.pattern, A1.pagetitle, A1.content, A2.value) AS rank 
FROM mod_site_content A1 LEFT JOIN 
    mod_site_tmplvar_contentvalues A2 
    ON A1.id = A2.contentid AND A2.tmplvarid IN (15, 17) CROSS JOIN 
    (SELECT ? as pattern) vars 
HAVING rank > 0 
ORDER BY rank; 

На данный момент, у вас есть только шаблон один раз, так что это должно работать , если ваша модель не имеет подстановочные знаки:

SELECT DISTINCT A1.pagetitle, A1.content, A1.uri, A2.value, 
     field(?, A1.pagetitle, A1.content, A2.value) AS rank 
FROM mod_site_content A1 LEFT JOIN 
    mod_site_tmplvar_contentvalues A2 
    ON A1.id = A2.contentid AND A2.tmplvarid IN (15, 17) 
HAVING rank > 0 
ORDER BY rank; 
+0

Спасибо за ответ. Я не совсем уверен, как правильно его реализовать (моя ошибка не включает полный запрос). Я отредактировал свой ответ, чтобы отразить это, если вы сможете подробно остановиться на своем подходе. – verism

+0

Придется попробовать их позже - спасибо за обновления. – verism

0

с риском downvotes, так как я на самом деле не ПРОБОВАЛИ это решение, я 'd попробовать что-то в этом направлении:

$sql = "SELECT DISTINCT A1.pagetitle, A1.content, A1.uri, A2.value, ". 
      "CASE ". 
       "WHEN A1.pagetitle LIKE CONCAT('%', :my_str, '%') THEN 1 ". 
       "WHEN A1.content LIKE CONCAT('%', :my_str, '%') THEN 2 ". 
       "WHEN A2.value LIKE CONCAT('%', :my_str, '%') THEN 3 ". 
       ...etc 

$pdo->bindValue(':my_str', $stuff); 
+0

Я думаю, что вы не можете связать именованные параметры более одного раза - вот почему я использую «?» вместо. – verism

+0

Я думаю, что исправлено. Не могли бы вы попытаться запустить этот пример, чтобы подтвердить, что он работает или не работает для вашей версии PHP? –

+0

SQLSTATE [HY093]: Недопустимый номер параметра – verism