如何在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','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','18')#2 /var/www/clientreachapi.com/releases/2018_03_10_14_54_58/src/Rb/ReportingApiBundle/Command/ClientBelowThresholdReportCommand.php(61):Rb \ ReportingApiBundle \ ClientThreshold \ ClientBelowThresholdReport-> getClientsWithBalanceBelowThreshold('120.00','18','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 \ ClientBelowThresholdReportCommand-> execute(对象(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(对象(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(Object(Rb \ ReportingApiBundle \ Command \ ClientBelowThresholdReportCommand),Object(Symfony \ Component \ Console \ Input \ ArgvInput),Object(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-> doRun(对象(Symfony \ Component \ Console \ Input \ ArgvInput),对象(Symfony \ Component \ Console \ Output \ ConsoleOutput))#7 / var / www / cl ientreachapi.com/releases/2018_03_10_14_54_58/vendor/symfony/symfony/src/Symfony/Component/Console/Application.php(123):Symfony \ Bundle \ FrameworkBundle \ Console \ Application-> doRun(Object(Symfony \ Component \ Console \)输入\ 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 (对象(Symfony \ Component \ Console \ Input \ ArgvInput))#9
1 回答
我想当你在查询中引用
:beginDaysAgo
和:totalDays
时,它们将被解释为文字字符串而不是参数的占位符 . 我建议从SQL中删除引号和days
部分,只留下占位符,如下所示:然后在将它们绑定到预准备语句之前将
days
部分附加到数值: