【问题标题】:Exception in PL/pgSQL functionPL/pgSQL 函数中的异常
【发布时间】:2013-11-15 10:34:30
【问题描述】:

我有一个关于 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;

对于 num_of_letters 必须返回异常: --SELECT info_about_reservoir(7) -- no_data_found --SELECT info_about_reservoir(8) -- too_many_rows --SELECT info_about_reservoir(9) -- 名称:% ...

在此脚本的先前版本中,我只返回了异常和错误:查询没有结果数据的目的地。现在它回来了 7:姓名:... 对于 8:名称:来自某些行查询的第一行 ... 对于 9:名称:来自一行查询的行 ...


对不起,我有一个答案:

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

【问题讨论】:

  • 您应该将您的答案添加为实际答案。
  • 然后你可以在一天后回来接受你自己的答案。
  • 您能否通过table-qualifying它们来澄清代码中哪个列属于哪个表?这是一个很好的做法,我怀疑那里仍然存在小故障..

标签: sql postgresql exception-handling plpgsql


【解决方案1】:

基于您缺少的表定义的假设。

您最新版本中的RIGHT [OUTER] JOIN 没有任何作用。由于条件在左表上,您也可以使用[INNER] JOIN。 你真的想要LEFT JOIN吗?那么没有匹配的repository_type的水库还是会返回?

STRICT modifier in SELECT INTO 仅考虑是否返回单行,它不会对 LEFT 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。目的是什么?

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-04-24
    • 2012-07-16
    • 1970-01-01
    • 2018-02-10
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多