如何声明在 PostgreSQL 9.3 查询中使用的变量?
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';
ERROR: type "cod_instance" does not exist SQL state: 42704 Character: 383
您的演示功能将像这样工作:
CREATE or REPLACE FUNCTION public.test()
RETURNS int4
LANGUAGE plpgsql 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$;
您不能使用
SET
来分配变量。这就是用于设置运行时参数的 SQL 命令 SET
。
但是你可以在声明时分配一个变量,甚至可以使用子查询。
@a_horse_with_no_name 已经写过有关命名冲突的文章。
在调试代码时使用干净的格式会有很大帮助......
您可能可以简化为:
CREATE OR REPLACE FUNCTION public.test(_cod_process bigint = 30001)
RETURNS integer
LANGUAGE sql 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$;
致电:
SELECT public.test(); -- for default 30001
SELECT public.test(1234);
根据
utc_log
的实际数据类型,您可能需要 now() AT TIME ZONE 'UTC'
。参见:
您需要在实际代码块中使用
into
子句运行选择,而不是在 declare
块中:
begin
select max(cod_instance)
into cod_instance
from public.instance
where public.instance.cod_process=cod_process;
....
end;
给变量(或参数)赋予与表中的列相同的名称通常不是一个好主意。在某些情况下,这可能会使解析器感到困惑。为了避免任何潜在的问题,请尝试为变量使用不同的名称,例如通过给它们添加前缀(例如
l_cod_process
代替 cod_process
或 l_cod_instance
代替 cod_instance
)
有关变量赋值的更多详细信息可以在手册中找到:http://www.postgresql.org/docs/current/static/plpgsql-statements.html