Как использовать параметр внутри строки в Postgres AND PHP 5.6? - PullRequest
0 голосов
/ 07 мая 2018

Как использовать параметр внутри цитаты с Postgres? Я получаю сообщение об ошибке: "SQLSTATE[HY093]: Invalid parameter number: :beginDaysAgo"

Когда мы смотрим на эти строки:

WHERE a.balance <= (a.autorefill_threshold+:amountAboveThreshold)
    AND ((t.created_at <= ( current_timestamp-INTERVAL  \':beginDaysAgo days\')) AND ( t.created_at >= (current_timestamp) - INTERVAL \':totalDays days\'))

Первый параметр не генерирует ошибку для меня. Это те, которые находятся внутри цитаты.

Это означает, что первый параметр, amountAboveThreshold работает, но он явно не может искать в строке.

В основном, когда я просто использую переменную PHP внутри, а не параметр, она работает отлично, или когда я просто вставляю число. Так, например, когда я ставлю число 20, а затем 21 для этих двух параметров, beginDaysAgo и totalDays соответственно работает отлично.

Но когда я пытаюсь использовать параметры - это правильный и безопасный способ сделать это - это не работает.

 public function getClientsWithBalanceBelowThreshold(
    $amountAboveThreshold=100.00,
    $beginDaysAgo = 0,
    $amountOfDays = 1
) {

    $totalDays = $amountOfDays + $beginDaysAgo;
    //this one works
    if ((double)$amountAboveThreshold!=$amountAboveThreshold)
        throw new \TypeError("Type Mismatch");
    $conn = $this->em->getConnection();


$conn = $this->em->getConnection();
        $sql = '
          SELECT DISTINCT ON (l.public_id) a.balance, a.public_id as account_public_id, a.organization_name, a.autorefill_threshold,
          l.name  as listing_name, l.paused, l.public_id,
          t.balance_before,
          t.balance_after, t.created_at, t.type
        FROM transaction as t INNER JOIN account a
            ON t.account_id = a.account_id
        INNER JOIN listing as l ON a.account_id = l.account_id
        WHERE a.balance <= (a.autorefill_threshold+:amountAboveThreshold)
        AND ((t.created_at <= ( current_timestamp-INTERVAL  \':beginDaysAgo days\')) AND ( t.created_at >= (current_timestamp) - INTERVAL \':totalDays days\'))
        AND t.balance_before !=  t.balance_after
        AND t.type != \'credit\'
        ORDER BY  l.public_id, a.balance DESC, t.created_at, l.account_id;
        ';
    $stmt = $conn->prepare($sql);
    $stmt->bindParam('amountAboveThreshold', $amountAboveThreshold);
    $stmt->bindParam('beginDaysAgo', $beginDaysAgo);
    $stmt->bindParam('totalDays', $totalDays);
    $stmt->execute();
    var_dump($stmt->fetchAll());die;

Я получаю полную ошибку ...

"SQLSTATE [HY093]: недопустимый номер параметра:: beginDaysAgo" # 0 /var/www/clientreachapi.com/releases/2018_03_10_14_54_58/vendor/doctrine/db al / lib / Doctrine / DBAL / Statement.php (141): Doctrine \ DBAL \ Driver \ PDOStatement-> bindParam ('beginDaysAgo', 'beginDaysAgo', «18», 2, NULL)
# 1 /var/www/clientreachapi.com/releases/2018_03_10_14_54_58/src/Rb/ReportingApiBundle/ClientThreshold/ClientBelowThresholdReport.php(77): Doctrine \ DBAL \ Statement-> bindParam ('beginDaysAgo *' '10 # 2 /var/www/clientreachapi.com/releases/2018_03_10_14_54_58/src/Rb/ReportingApiBundle/Command/ClientBelowThresholdReportCommand.php(61): Rb \ ReportingApiBundle \ ClientThreshold \ ClientBelowThуп 2' ) * * тысяча двадцать-один # 3 /var/www/clientreachapi.com/releases/2018_03_10_14_54_58/vendor/symfony/symfony/src/Symfony/Component/Console/Command/Command.php(259): Rb \ ReportingApiBundle \ Command \resholdBortThreeThlowThlowThis (Symfony \ Component \ Console \ Input \ ArgvInput), объект (Symfony \ Component \ Console \ Output \ ConsoleOutput))
# 4 /var/www/clientreachapi.com/releases/2018_03_10_14_54_58/vendor/symfony/symfony/src/Symfony/Component/Console/Application.php(863): Symfony \ Component \ Console \ Command \ Command-> run (Object (Symfony \ Component \ Console \ Input \ ArgvInput), объект (Symfony \ Component \ Console \ Output \ ConsoleOutput))
# 5 /var/www/clientreachapi.com/releases/2018_03_10_14_54_58/vendor/symfony/symfony/src/Symfony/Component/Console/Application.php(192): Symfony \ Component \ Console \ Application-> doRunCommand ( \ ReportingApiBundle \ Command \ ClientBelowThresholdReportCommand), объект (Symfony \ Component \ Console \ Input \ ArgvInput), объект (Symfony \ Component \ Console \ Output \ ConsoleOutput))
# 6 /var/www/clientreachapi.com/releases/2018_03_10_14_54_58/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Console/Application.php(92): Symfony \ Component \ Console \ Application-> doR (Symfony \ Component \ Console \ Input \ ArgvInput), объект (Symfony \ Component \ Console \ Output \ ConsoleOutput))
# 7 /var/www/clientreachapi.com/releases/2018_03_10_14_54_58/vendor/symfony/symfony/src/Symfony/Component/Console/Application.php(123): Symfony \ Bundle \ FrameworkBundle \ Console \ Application-> do (Symfony \ Component \ Console \ Input \ ArgvInput), объект (Symfony \ Component \ Console \ Output \ ConsoleOutput))
# 8 /var/www/clientreachapi.com/releases/2018_03_10_14_54_58/app/console(29): Symfony \ Component \ Console \ Application-> run (Object (Symfony \ Component \ Console \ Input \ ArgvInput))
# 9 {main}

1 Ответ

0 голосов
/ 07 мая 2018

Я думаю, что если в запросе указаны :beginDaysAgo и :totalDays, они будут интерпретироваться как буквенные строки, а не как заполнители для параметров. Я бы предложил удалить кавычки и часть days из SQL и оставить только заполнители, например:

(t.created_at <= (current_timestamp - INTERVAL :beginDaysAgo))
AND ( t.created_at >= (current_timestamp - INTERVAL :totalDays))

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

$beginDaysAgo = "$beginDaysAgo days";
$amountOfDays = "$amountOfDays days";
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...