これはおそらくばかげた質問のように聞こえますが、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
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
デモ関数は次のように機能します。
_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
と見なされます。
しかし、宣言時に変数を割り当てることができます。そのためにサブクエリを使用することもできます。
Use _LANGUAGE plpgsql
_ではなく _。識別子です。LANGUAGE 'plpgsql'
_
@ a_horse_with_no_name はすでに名前の競合について書いています。
クリーンなフォーマットを使用すると、コードをデバッグするときに長い時間がかかります...
しかし、おそらく次のように簡略化できます。
_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;
_
コール:
_SELECT public.test(); -- for default 30001
SELECT public.test(1234);
_
そして、_utc_log
_の実際のデータ型によっては、おそらくnow() AT TIME ZONE 'UTC'
が必要です。