1

PL/pgSQL の例外に関する小さな問題があります。私の仕事は、特定の長さのリザーバーを見つける関数を書くことです。

私のコード:

create or replace function
 info_about_reservoir(num_of_letters int)
 returns int as
$$
 declare
  res_name varchar(50);
  res_type varchar(50);
  res_area decimal(10,0);
  counter int := 1;
 begin
  select r_name,t_name,r_area into strict res_name,res_type,res_area
  from 
   reservoirs right outer join reservoirs_types 
   on t_id=r_t_id
  where char_length(r_nazwa)=$1;
  raise notice 'Name: %, type: %, area: %',res_name,res_type,res_area;
  exception
   when no_data_found then
    raise notice 'No reservoir with name lenght %',$1;
   when too_many_rows then
    raise notice 'Too much reservoirs with name lenght %',$1;
  return counter;
 end;
$$ language plpgsql;

--SELECT info_about_reservoir(7) -- no_data_found --SELECT info_about_reservoir(8) -- too_many_rows --SELECT info_about_reservoir(9) -- Name: % ...

このスクリプトの以前のバージョンでは、例外と ERROR: query has no destination for result data のみが返されました。7 の場合: 名前: ... 8 の場合: 名前: いくつかの行のクエリの最初の行 ... 9 の場合: 名前: 1 つの行のクエリの行 ...


混乱して申し訳ありませんが、これに対する答えがあります:

create or replace function
 info_about_reservoir(num_of_letters int)
 returns int as
$$
 declare
  res_name varchar(50);
  res_type varchar(50);
  res_area int;
  counter int := 1;
 begin
  select r_name,t_name,r_area into strict res_name,res_type,res_area
  from 
   reservoirs right outer join reservoirs_types 
   on t_id=a_t_id
  where char_length(r_name)=$1;
  raise notice 'Name: %, type: %, area: %',res_name,res_type,res_area;
  return counter;
  exception
   when no_data_found then
    raise notice 'No reservoir with name lenght %',$1;
    return counter;
   when too_many_rows then
    raise notice 'Too much reservoirs with name lenght %',$1;
    return counter;
 end;
$$ language plpgsql;

今では動作します。:D

4

1 に答える 1

1

欠落しているテーブル定義に関する仮定に基づいて構築します。

RIGHT [OUTER] JOIN最新バージョンの は何の役にも立ちません。状態は左表のとおりですので、 をご利用いただいても構いません[INNER] JOIN。あなたは実際に欲しいLEFT JOINですか?Reservers_type に一致しないリザーバーがまだ返されるようにするには?

STRICT修飾子はSELECT INTOLEFT JOIN、単一の行が返されるかどうかのみを考慮し、 (または個々の列に NULL 値が割り当てられている)の欠落した行には反応しません。

次のようになります。

CREATE OR REPLACE FUNCTION info_about_reservoir(num_of_letters int)
  RETURNS int AS
$func$
DECLARE
  res_name text;
  res_type text;
  res_area int;
  counter  int := 1;
BEGIN
   SELECT r_name, t_name, r_area  -- no table-qualification for lack of info
   INTO   STRICT res_name, res_type, res_area
   FROM   reservoirs r
   LEFT  JOIN reservoirs_types t ON t_id = a_t_id -- OR JOIN, not RIGHT JOIN
   WHERE  length(r_name) = $1;

   RAISE NOTICE 'Name: %, type: %, area: %', res_name, res_type, res_area;
   RETURN counter;

EXCEPTION
   WHEN no_data_found THEN
      RAISE NOTICE 'No reservoir with name length %.', $1;
      RETURN counter;
   WHEN too_many_rows THEN
      RAISE NOTICE 'Too many reservoirs with name length %.', $1;
      RETURN counter;
END
$func$ LANGUAGE plpgsql;
  • counterは常に1。目的は何ですか?
于 2013-11-04T19:59:55.197 に答える