如何在使用交叉表时在Postgresql中准备语句

时间:2016-08-29 16:26:28

标签: php postgresql symfony doctrine prepared-statement

使用Symfony(2.8)和Doctrine,使用Postgresql(9.5)。我需要使用crosstab来使用PHP中的预处理语句来转换结果。

我的架构不同而且复杂,所以为了简单起见,让我们直接从Postgresql的documentation中获取示例表:

CREATE TABLES sales(year int, month int, qty int);
INSERT INTO sales VALUES(2007, 1, 1000);
INSERT INTO sales VALUES(2007, 2, 1500);
INSERT INTO sales VALUES(2007, 7, 500);
INSERT INTO sales VALUES(2007, 11, 1500);
INSERT INTO sales VALUES(2007, 12, 2000);
INSERT INTO sales VALUES(2008, 1, 1000);

现在,这是PHP代码:

$sql = "SELECT * from CROSSTAB(
    'SELECT year, month, qty FROM sales WHERE year = :year',
    'SELECT m FROM generate_series(1,12) m'
  ) as (
    year int,
    \"Jan\" int,
    \"Feb\" int,
    \"Mar\" int,
    \"Apr\" int,
    \"May\" int,
    \"Jun\" int,
    \"Jul\" int,
    \"Aug\" int,
    \"Sep\" int,
    \"Oct\" int,
    \"Nov\" int,
    \"Dec\" int
  );";

    $statement = $conn->prepare($sql);
    $params = ['year' => 2008];

    $statement->execute($params);

执行此操作会抛出错误:

SQLSTATE[HY093]: Invalid parameter number: :year

我认为这可能是因为:year被视为字符串文字的一部分,因此,它无法绑定它。我该如何工作?有解决方法吗?

1 个答案:

答案 0 :(得分:2)

你是对的。引用的占位符不是占位符。它们只是字符串的一部分,只有像占位符一样的LOOK。相反,构建字符串文字:

$sql = "select * from crosstab(
    'select year, month, qty from sales order by 1 where year = ' + :year,
                                                                ^^^^^^^^^