2017-02-09 6 views
1

내 함수에서 복합 배열 유형에 데이터를 삽입하려고합니다. 복합 배열 형식의 INPUT 매개 변수에서 데이터를 받아 들여 데이터를 동일한 유형의 OUPUT 매개 변수에 저장해야합니다.PostgreSQL의 OUTPUT 매개 변수로 복합 배열 유형

CREATE TYPE public.type_x_type AS (x integer); 

CREATE TYPE public.type_y_type AS(x integer,y integer); 

내 기능은

CREATE OR REPLACE FUNCTION GET_PRICE_PC_X 
    (
    IP_PRICE_INFO IN TYPE_X_TYPE[], 
    PC_COST OUT TYPE_Y_TYPE[], 
    OP_RESP_CODE OUT VARCHAR, 
    OP_RESP_MSG OUT VARCHAR 
) 
RETURNS RECORD AS $$ 
DECLARE 
    SELECTED_PRICE CURSOR(IP_PFCNTR INT) 
    FOR 
    SELECT ID, PHONE FROM CUSTOMER WHERE ID=IP_PFCNTR; 
    J NUMERIC(10); 
BEGIN 
J := 0; 
    FOR I IN ARRAY_LOWER(IP_PRICE_INFO,1) .. ARRAY_UPPER(IP_PRICE_INFO,1) 
    LOOP 
    FOR K IN SELECTED_PRICE(IP_PRICE_INFO[I].X) 
    LOOP 
    PC_COST := ROW(K.ID,K.PHONE); 
END LOOP; 
    END LOOP; 
    OP_RESP_CODE :='000'; 
    OP_RESP_MSG :='Success'; 
EXCEPTION 
WHEN OTHERS THEN 
    OP_RESP_CODE :='200'; 
    OP_RESP_MSG :=SQLERRM; 
END; 
$$ language 'plpgsql'; 

select * from GET_PRICE_PC_X(ARRAY[ROW(1)] :: TYPE_X_TYPE[]); 

내가 아래의 오류를 받고 있어요.

PC_COST | OP_RESPONSE_CODE | OP_RESP_MSG 
--------------------------------------------------------- 
      | 200    | malformed array literal: "(1,30003)" 

나는 OUT 유형을 어딘가에 불러올 것이므로 데이터를 배열에 삽입해야합니다.

답변

2

함수를 개발할 때는 WHEN OTHERS을 사용하지 마십시오. 디버깅은 끔찍한 일입니다. 함수의 문제는 배열에 복합 유형을 할당하는 것입니다.

PC_COST := ROW(K.ID,K.PHONE); 

잘못된 것입니다. 아마 당신은 추가 할 것입니다. 아마도 덜 읽을 수 있지만, 속도가 매우 빠르고 - - 속도가 느려질 수 있습니다 중첩 된 쿼리 루프 (빠른 간단한 SELECT 이상을 실행

결정적인 부분은

J := 0; PC_COST := '{}'; 
FOR I IN ARRAY_LOWER(IP_PRICE_INFO,1) .. ARRAY_UPPER(IP_PRICE_INFO,1) 
LOOP 
    FOR K IN SELECTED_PRICE(IP_PRICE_INFO[I].X) 
    LOOP 
    PC_COST := PC_COST || ROW(K.ID,K.PHONE)::type_y_type; 
    END LOOP; 
END LOOP; 
귀하의 기능을 하나 개의 쿼리로 대체 될 수

처럼 보이도록해야 더 사소한 SELECT들) :

CREATE OR REPLACE FUNCTION public.get_price_pc_x(ip_price_info type_x_type[], 
               OUT pc_cost type_y_type[], 
               OUT op_resp_code character varying, 
               OUT op_resp_msg character varying) 
RETURNS record 
LANGUAGE plpgsql STABLE 
AS $function$ 
BEGIN 
    pc_cost := ARRAY(SELECT ROW(id, phone)::type_y_type 
        FROM customer 
        WHERE id IN (SELECT (unnest(ip_price_info)).x)); 
    OP_RESP_CODE :='000'; 
    OP_RESP_MSG :='Success'; 
EXCEPTION 
    WHEN OTHERS THEN 
    OP_RESP_CODE :='200'; 
    OP_RESP_MSG :=SQLERRM; 
END; 
$function$; 

참고 : 사이클 변수에 대한 NUMERIC 유형을 사용은 잘못된 생각이다 -이 유형의 비용이 단지 돈이나 귀중한 계산에 사용되어야한다. int 유형은이 장소에서 절대적으로 정확합니다. 이 함수가 실패 할 이유가없는 - - 오류 처리가 안 -

는 일반적으로 당신은 당신이 더 많은 기능을 감소시킬 수있다 (안 처리 할 수있는 이유)

CREATE OR REPLACE FUNCTION public.get_price_pc_x(ip_price_info type_x_type[]) 
RETURNS type_y_type[] 
LANGUAGE sql STABLE 
AS $function$ 
    SELECT ARRAY(SELECT ROW(id, phone)::type_y_type 
        FROM customer 
        WHERE id IN (SELECT (unnest(ip_price_info)).x)); 
$function$; 
+0

안녕 파벨, 당신 정말 내 코드를 깔끔하게 보이게 만들었습니다. :) 어쨌든 도와 줘서 고마워. 질문이 하나 있습니다. 출력에서 한 열에 액세스하려면 어떻게해야합니까? 내 출력은 "{"(31,23423423) ","(1,300074321) "}"처럼 보입니다. 그리고 왜 PC_COST : = '{}'; 그것은 intializing 뭔가 같은 것입니다. – user1720827

+0

(중첩 (결과)). 필드; '{}'은 빈 배열에 대한 특수 리터럴입니다. PC_COST의 기본값은 NULL이고 NULL + any는 다시 NULL입니다. 따라서 PC_COST는 빈 배열로 초기화되어야합니다. - '{}' –