'Declare variable set = select
How do I declare a variable for used in a PostgreSQL 9.3 query?
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
Solution 1:[1]
You need to run the select using the into
clause inside the actual code block, not in the declare
block:
begin
select max(cod_instance)
into cod_instance
from public.instance
where public.instance.cod_process=cod_process;
....
end;
It's usually not such a good idea to give variables (or parameters) the same name as columns in the table. There are certain cases where this can confuse the parser. To avoid any potential problems, try to use different names for your variables, e.g. by prefixing them (e.g. l_cod_process
instead of cod_process
or l_cod_instance
instead of cod_instance
)
More details on variable assignment can be found in the manual: http://www.postgresql.org/docs/current/static/plpgsql-statements.html
Solution 2:[2]
Your demo function would work like this:
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;
Major points
You cannot use
SET
to assign a variable. That's taken to be the SQL commandSET
for setting run-time parameters.But you can assign a variable at declaration time, even use a subquery for that.
Use
LANGUAGE plpgsql
, not. It's an identifier.LANGUAGE 'plpgsql'
@a_horse_with_no_name already wrote about naming conflicts.
Using a clean format goes a long way when debugging code ...
But you can probably simplify to:
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;
Call:
SELECT public.test(); -- for default 30001
SELECT public.test(1234);
And depending on the actual data type of utc_log
you probably want now() AT TIME ZONE 'UTC'
:
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | |
Solution 2 | Community |