Declare variable set = select
这听起来可能是一个非常愚蠢的问题,但是我如何声明一个用于PostgreSQL 9.3查询的变量呢?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | CREATE OR REPLACE FUNCTION public.test() RETURNS int4 AS $BODY$ DECLARE cod_process BIGINT :=30001; cod_instance BIGINT ; utc_log TIMESTAMP WITHOUT TIME zone := localtimestamp; cod_log_type VARCHAR(100) :='information '; txt_log_text VARCHAR(100):= 'start process'; txt_log VARCHAR(100):= txt_log_text||'_'||cod_process; SET cod_instance= SELECT MAX(cod_instance) AS cod_instance FROM public.instance WHERE public.instance.cod_process=cod_process; BEGIN INSERT INTO public.log (cod_process, cod_instance, utc_log,cod_log_type,txt_log) VALUES (cod_process, cod_instance, utc_log,cod_log_type,txt_log ); RETURN 11; END; $BODY$ LANGUAGE 'plpgsql'; |
1
2
3 ERROR: TYPE"cod_instance" does NOT exist
SQL state: 42704
CHARACTER: 383
演示功能的工作方式如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | CREATE OR REPLACE FUNCTION public.test() RETURNS int4 AS $func$ DECLARE _cod_process BIGINT := 30001; _cod_instance BIGINT := (SELECT MAX(cod_instance) FROM public.instance WHERE cod_process = _cod_process); _utc_log TIMESTAMP := localtimestamp; _cod_log_type VARCHAR(100) := 'information'; _txt_log_text VARCHAR(100) := 'start process'; _txt_log VARCHAR(100) := txt_log_text || '_' || cod_process; BEGIN INSERT INTO public.log ( cod_process, cod_instance, utc_log, cod_log_type, txt_log) VALUES (_cod_process, _cod_instance, _utc_log, _cod_log_type, _txt_log); RETURN 11; END $func$ LANGUAGE plpgsql; |
要点
不能使用
SET 来分配变量。这就是用于设置运行时参数的SQL命令SET 。但您可以在声明时分配一个变量,甚至为此使用子查询。
使用
LANGUAGE plpgsql ,而不是LANGUAGE 'plpgsql' 。它是一个标识符。@一个没有名字的马已经写了关于命名冲突的文章。
在调试代码时,使用干净的格式有很长的路要走…
但您可能可以简化为:
1 2 3 4 5 6 7 8 9 10 11 | CREATE OR REPLACE FUNCTION public.test(_cod_process BIGINT = 30001) RETURNS INTEGER AS $func$ INSERT INTO public.log (cod_process, cod_instance , utc_log, cod_log_type , txt_log) SELECT $1, MAX(cod_instance), now() , 'information', 'start process_' || $1 FROM public.instance WHERE cod_process = $1 GROUP BY cod_process RETURNING 11 $func$ LANGUAGE SQL; |
呼叫:
1 2 | SELECT public.test(); -- for default 30001 SELECT public.test(1234); |
根据
- 在Rails和PostgreSQL中完全忽略时区
您需要在实际代码块内使用
1 2 3 4 5 6 7 8 | BEGIN SELECT MAX(cod_instance) INTO cod_instance FROM public.instance WHERE public.instance.cod_process=cod_process; .... END; |
给变量(或参数)赋予与表中的列相同的名称通常不是一个好主意。在某些情况下,这可能会混淆解析器。为了避免任何潜在的问题,请尝试对变量使用不同的名称,例如,在变量前面加上前缀(例如,
有关变量分配的更多详细信息,请参见手册:http://www.postgresql.org/docs/current/static/plpgsql-statements.html