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'; | 
2
3
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