EXECUTE <query-string> USING value1... 在第一个替换占位符 ($1) 上阻塞
EXECUTE <query-string> USING value1... chokes on first substitution-placeholder ($1)
以下代码在 "dollar-one" 占位符处失败,我不确定原因。我试图确定我是否在这里遗漏了一些语义,或者这是否是一个实际的 Postgresql 核心错误,可以由下面显示的代码支持。
-- Attempt to run the following on any database.
-- Creating the relations of the correct names etc. should not be necessary,
-- as the error occurs before this would even matter.
-- The code below fails in an unexpected way because no substitution appears
-- to take place.
--
-- ERROR: syntax error at or near ""
-- LINE 3: special_constraint_trigger(,,);
-- ^
-- SQL state: 42601
-- Context: PL/pgSQL function inline_code_block line 11 at EXECUTE statement
--
DO LANGUAGE plpgsql $$
DECLARE
-- simulated parameters:
referencing_table TEXT = 'the_great_referencer';
referencing_column TEXT = 'fk_field';
referenced_column TEXT = 'measurement_id';
-- :simulated parameters
BEGIN
EXECUTE 'CREATE CONSTRAINT TRIGGER maybe_throw_some_exceptions AFTER UPDATE OR DELETE ON measurement
DEFERRABLE INITIALLY DEFERRED FOR EACH ROW EXECUTE PROCEDURE
special_constraint_trigger(,,);'
USING referenced_column,referencing_table, referencing_column;
END;
$$;
其他人是否清楚为什么这个 USING
替换不起作用?我希望上面的内容能够简单地打破这里引用了伪造的表和列的事实,但在我的系统上,Postgres 似乎更关心未替换的美元符号。特别是如果其他人能够重现此错误,我将计划将此作为错误归档。
版本信息:x86_64-redhat-linux-gnu 上的 PostgreSQL 9.2.14,由 gcc (GCC) 4.8.3 20140911 (Red Hat 4.8.3-9) 编译,64 -位
OS: Linux 4.1.10-17.31.amzn1.x86_64 #1 SMP 10 月 24 日星期六 01:31:37协调世界时 2015 x86_64 x86_64 x86_64 GNU/Linux
您的代码应该不起作用 - 参数只能与带有计划的 SQL 语句一起使用。 DML(INSERT
, UPDATE
, DELETE
) 和SELECT
都是带有计划的语句。 DDL 语句没有计划,所以不应该被参数化。因此,您不能将子句 USING
用于任何 DDL 语句,例如 CREATE
、ALTER
、DROP
。您必须执行一些不带任何参数的 SQL 字符串 - 以下代码应该有效:
BEGIN
EXECUTE format('CREATE CONSTRAINT TRIGGER maybe_throw_some_exceptions
AFTER UPDATE OR DELETE ON measurement
DEFERRABLE INITIALLY DEFERRED
FOR EACH ROW EXECUTE PROCEDURE
special_constraint_trigger(%I,%I,%I)',
referenced_column,
referencing_table,
referencing_column);
END;
以下代码在 "dollar-one" 占位符处失败,我不确定原因。我试图确定我是否在这里遗漏了一些语义,或者这是否是一个实际的 Postgresql 核心错误,可以由下面显示的代码支持。
-- Attempt to run the following on any database.
-- Creating the relations of the correct names etc. should not be necessary,
-- as the error occurs before this would even matter.
-- The code below fails in an unexpected way because no substitution appears
-- to take place.
--
-- ERROR: syntax error at or near ""
-- LINE 3: special_constraint_trigger(,,);
-- ^
-- SQL state: 42601
-- Context: PL/pgSQL function inline_code_block line 11 at EXECUTE statement
--
DO LANGUAGE plpgsql $$
DECLARE
-- simulated parameters:
referencing_table TEXT = 'the_great_referencer';
referencing_column TEXT = 'fk_field';
referenced_column TEXT = 'measurement_id';
-- :simulated parameters
BEGIN
EXECUTE 'CREATE CONSTRAINT TRIGGER maybe_throw_some_exceptions AFTER UPDATE OR DELETE ON measurement
DEFERRABLE INITIALLY DEFERRED FOR EACH ROW EXECUTE PROCEDURE
special_constraint_trigger(,,);'
USING referenced_column,referencing_table, referencing_column;
END;
$$;
其他人是否清楚为什么这个 USING
替换不起作用?我希望上面的内容能够简单地打破这里引用了伪造的表和列的事实,但在我的系统上,Postgres 似乎更关心未替换的美元符号。特别是如果其他人能够重现此错误,我将计划将此作为错误归档。
版本信息:x86_64-redhat-linux-gnu 上的 PostgreSQL 9.2.14,由 gcc (GCC) 4.8.3 20140911 (Red Hat 4.8.3-9) 编译,64 -位
OS: Linux 4.1.10-17.31.amzn1.x86_64 #1 SMP 10 月 24 日星期六 01:31:37协调世界时 2015 x86_64 x86_64 x86_64 GNU/Linux
您的代码应该不起作用 - 参数只能与带有计划的 SQL 语句一起使用。 DML(INSERT
, UPDATE
, DELETE
) 和SELECT
都是带有计划的语句。 DDL 语句没有计划,所以不应该被参数化。因此,您不能将子句 USING
用于任何 DDL 语句,例如 CREATE
、ALTER
、DROP
。您必须执行一些不带任何参数的 SQL 字符串 - 以下代码应该有效:
BEGIN
EXECUTE format('CREATE CONSTRAINT TRIGGER maybe_throw_some_exceptions
AFTER UPDATE OR DELETE ON measurement
DEFERRABLE INITIALLY DEFERRED
FOR EACH ROW EXECUTE PROCEDURE
special_constraint_trigger(%I,%I,%I)',
referenced_column,
referencing_table,
referencing_column);
END;