2013-11-04 28 views
1

我在PL/pgSQL中有關於異常的小問題。我的任務是寫一個函數來查找一定長度的水庫。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

+4

您應該添加您的一個作爲一個實際的答案。 –

+1

然後你可以回來一天,接受你自己的答案。 –

+0

您可以通過* table-qualifying *他們來澄清哪些列屬於您的代碼中的哪個表?首先,這是一個很好的做法,我懷疑那裏仍然存在一個小故障.. –

回答

1

基於對您缺少的表定義的假設。

最新版本中的RIGHT [OUTER] JOIN沒有任何用處。由於條件在左邊的表格中,所以您最好使用[INNER] JOIN。 你真的想要一個LEFT JOIN嗎?那麼沒有匹配reservoirs_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。有什麼目的?