2013-11-04 2 views
1

PL/pgSQL에서 예외에 관한 작은 문제가 있습니다. 내 임무는 특정 길이의 저수지를 찾는 함수를 작성하는 것이다.PL/pgSQL 함수에서의 예외

내 코드 : 예외를 반환해야합니다 num_of_letters를 들어

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) - 이름 : % ...

이 스크립트의 이전 버전에서는 예외 만 반환했으며 ERROR : 쿼리에는 결과 데이터의 대상이 없습니다. 이름 : 지금은 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

당신은 당신의를 추가해야 nswer는 실제 답변입니다. –

+1

그리고 나서 하루 만에 돌아와서 자신의 대답을 받아 들일 수 있습니다. –

+0

* 테이블 규정 *을 통해 코드에서 어떤 테이블에 속하는 열을 명확히 할 수 있습니까? 그것은 시작하는 것이 좋은 습관이고 나는 거기에 여전히 결함이 있다고 의심합니다. –

답변

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이다. 목적이야?