我正在尝试在我的函数中将数据插入到复合数组类型中。它应接受来自复合数组类型的INPUT参数的数据,并将数据存储到相同类型的OUPUT参数中。
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类型,因此我需要将数据插入到数组中。
答案 0 :(得分:2)
开发功能时,请勿使用WHEN OTHERS
。调试很糟糕。您的函数问题是将复合类型赋值给数组
PC_COST := ROW(K.ID,K.PHONE);
这是错误的。可能你会做追加。
关键部分应该看起来像
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
比更简单的SELECT
更快): / p>
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$;