在EXECUTE中使用的部分被忽略...在PL / pgSQL中使用

时间:2014-05-21 08:37:00

标签: postgresql plpgsql dynamic-sql postgresql-9.3

我尝试通过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部分和美元符号转义值对我不起作用?

1 个答案:

答案 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是某种类型的整数。如果不是,请在此处使用显式转换。