在 Yii2 中使用 plpgsql 绑定查询值
Bind values for query with plpgsql in Yii2
我用 Yii2 DAO 执行 SQL 查询。
$db->createCommand("
DO $$
DECLARE
rec RECORD;
pos INT := 0;
BEGIN
FOR rec IN (SELECT * FROM table1 WHERE "type" = :t LOOP
UPDATE table1 SET position = pos WHERE id = rec.id;
pos := pos + 2;
END LOOP;
END;
$$ language 'plpgsql'
", [':t' => 0])->execute();
但失败并出现错误:
SQLSTATE[42P18]: Indeterminate datatype: 7
ERROR: could not determine data type of parameter
type
列有 INT
类型。我尝试使用 [':t' => [0, \PDO::PARAM_INT]]
显式设置参数类型。但错误仍然存在。如果我将值直接连接到 SQL 字符串中,它会起作用,但这不是解决方案。 :t
只是该查询中的一个参数。
其他简单的 SQL 查询成功。此问题仅存在于带有过程的查询中。如果我 运行 来自 DataGrip 的这个查询,它就有效。但是在 PHP 它失败了。
为什么它不起作用,我如何为此类查询绑定参数?
如果您 create an actual function 并调用它,您可以传递 values 作为参数。
但是当您执行 DO
statement 时,函数体(在您的示例中包含在美元引号 $$
中)只是一个 字符串文字 。没有参数传递,也没有返回任何内容。您必须 将值作为字符串连接 到 plpgsql 代码中。
但你也不需要。请改用简单的 准备好的语句 。无论如何比循环便宜得多:
UPDATE table1 t
SET position = t1.pos
FROM (
SELECT id, (row_number() OVER () - 1) * 2 AS pos
FROM table1
WHERE "type" = :t
) t1
WHERE t.id = t1.id
现在传递参数值很简单。
旁白:结果是任意的,除非您将 ORDER BY
添加到 OVER
子句。你原来也有这个弱点。
相关:
- What are '$$' used for in PL/pgSQL
我用 Yii2 DAO 执行 SQL 查询。
$db->createCommand("
DO $$
DECLARE
rec RECORD;
pos INT := 0;
BEGIN
FOR rec IN (SELECT * FROM table1 WHERE "type" = :t LOOP
UPDATE table1 SET position = pos WHERE id = rec.id;
pos := pos + 2;
END LOOP;
END;
$$ language 'plpgsql'
", [':t' => 0])->execute();
但失败并出现错误:
SQLSTATE[42P18]: Indeterminate datatype: 7 ERROR: could not determine data type of parameter
type
列有 INT
类型。我尝试使用 [':t' => [0, \PDO::PARAM_INT]]
显式设置参数类型。但错误仍然存在。如果我将值直接连接到 SQL 字符串中,它会起作用,但这不是解决方案。 :t
只是该查询中的一个参数。
其他简单的 SQL 查询成功。此问题仅存在于带有过程的查询中。如果我 运行 来自 DataGrip 的这个查询,它就有效。但是在 PHP 它失败了。
为什么它不起作用,我如何为此类查询绑定参数?
如果您 create an actual function 并调用它,您可以传递 values 作为参数。
但是当您执行 DO
statement 时,函数体(在您的示例中包含在美元引号 $$
中)只是一个 字符串文字 。没有参数传递,也没有返回任何内容。您必须 将值作为字符串连接 到 plpgsql 代码中。
但你也不需要。请改用简单的 准备好的语句 。无论如何比循环便宜得多:
UPDATE table1 t
SET position = t1.pos
FROM (
SELECT id, (row_number() OVER () - 1) * 2 AS pos
FROM table1
WHERE "type" = :t
) t1
WHERE t.id = t1.id
现在传递参数值很简单。
旁白:结果是任意的,除非您将 ORDER BY
添加到 OVER
子句。你原来也有这个弱点。
相关:
- What are '$$' used for in PL/pgSQL