我尝试通过EXECUTE..USING动态制作一个序列,我有问题将参数传递给它。根据{{3}},我知道正确的形式应该是这样的:
CREATE OR REPLACE FUNCTION create_dyn_seq( /* some params */ )
RETURNS void AS $$
DECLARE
_seq_name text;
_min integer;
_max integer;
BEGIN
/*
some code assigning the variables
sample values:
_seq_name := 'hu01/1/0_seq';
_min := 101;
_max := 500;
*/
EXECUTE 'CREATE SEQUENCE "' || _seq_name || '" MINVALUE $1 MAXVALUE $2 '
USING _min::INT, _max::INT;
RETURN;
END;
$$ LANGUAGE plpgsql;
我添加了引号,_seq_name本身似乎没问题。但是,当我插入这些值时,它会抛出以下错误:
ERROR: syntax error at or near "$1"
LINE 1: CREATE SEQUENCE "hu01/1/0_seq" MINVALUE $1 MAXVALUE $2
我还尝试了EXECUTE的替代语法,如建议documentation:
EXECUTE
'CREATE SEQUENCE "' || _seq_name || '" MINVALUE ' || $1 || ' MAXVALUE ' || $2
USING _min::INT, _max::INT;
现在错误不同了:
ERROR: syntax error at or near "hu01"
LINE 1: CREATE SEQUENCE "hu01/1/0_seq" MINVALUE hu01 MAXVALUE 1
美元符号现在可以转换,但USING部分中的变量被_seq_name
变量的部分覆盖。我试图用下划线替换序列名称中的斜杠,但没有任何改变。
我也按照建议here通过format()
和USING一起尝试了,但没有任何改变,同样的错误发生了:
EXECUTE format('CREATE SEQUENCE %I MINVALUE $1 MAXVALUE $2 ', _seq_name)
USING _min::INT, _max::INT;
EXECUTE format('CREATE SEQUENCE %I MINVALUE ' || $1 || ' MAXVALUE ' || $2, _nazev_seq)
USING _min::INT, _max::INT;
然后我用format()
参数完全取代了USING部分:
EXECUTE format('CREATE SEQUENCE %I MINVALUE %L MAXVALUE %L ', _seq_name, _min::INT, _max::INT);
现在我几乎想要的地方,错误是不同的:
ERROR: syntax error at or near "'101'"
LINE 1: CREATE SEQUENCE "hu01/1/0_seq" MINVALUE '101' MAXVALUE '500'...
我在“here”上找到了一个问题,其中一个答案显示%s
。现在它起作用了:
EXECUTE format('CREATE SEQUENCE %I MINVALUE %s MAXVALUE %s ', _seq_name, _min, _max);
但是,how to use integer within FORMAT()建议在USING部分使用整数,如果没有错误,我会这样做。我的“解决方案”感觉是一个肮脏的解决方法,我想做得对,所以我的问题是:
为什么USING部分和美元符号转义值对我不起作用?
答案 0 :(得分:2)
EXECUTE 'CREATE SEQUENCE "' || _seq_name || '" MINVALUE $1 MAXVALUE $2 '
USING _min::INT, _max::INT;
这不起作用,因为参数替换将起作用only within SELECT, INSERT, UPDATE, and DELETE commands:
参数符号的另一个限制是它们只能在SELECT,INSERT,UPDATE和DELETE命令中使用。只有这些语句有执行计划,只有这些语句应该参数化。
EXECUTE 'CREATE SEQUENCE "' || _seq_name || '" MINVALUE ' || $1 || ' MAXVALUE ' || $2
USING _min::INT, _max::INT;
这不起作用,因为在该上下文中$1
引用了函数的1st argument。
EXECUTE format('CREATE SEQUENCE %I MINVALUE %L MAXVALUE %L ', _seq_name, _min::INT, _max::INT);
这不起作用,因为MINVALUE
和& MAXVALUE
语句的CREATE SEQUENCE
选项只接受整数,而不接受文本(并且不会在ddl中完成隐式转换)。
EXECUTE format('CREATE SEQUENCE %I MINVALUE %s MAXVALUE %s ', _seq_name, _min, _max);
只要_min
& _max
是某种类型的整数。如果不是,请在此处使用显式转换。