web-dev-qa-db-ja.com

変数セットの宣言=選択

これはおそらくばかげた質問のように聞こえますが、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
13
ASA

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

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 と見なされます。

  • しかし、宣言時に変数を割り当てることができます。そのためにサブクエリを使用することもできます。

  • 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'が必要です。

23