我有一個管道功能。如果我發現例外,我不想回傳任何行。即使在第一次使用管道行之后發生例外。
CREATE TYPE a_r IS OBJECT (a1 VARCHAR (1), a2 VARCHAR (1));
CREATE TYPE a_t IS TABLE OF a_r;
CREATE or replace FUNCTION get_a
RETURN a_t
PIPELINED
IS
BEGIN
FOR c IN (SELECT '1' a , '2' b FROM DUAL)
LOOP
PIPE ROW (a_r(c.a,c.b));
END LOOP;
FOR a
IN (SELECT 'a2' a,
'b' b
FROM DUAL)
LOOP
PIPE ROW (a_r(a.a,a.b));
END LOOP;
exception
WHEN VALUE_ERROR
THEN
DBMS_OUTPUT.put_line ('VALUE_ERROR');
WHEN OTHERS
THEN
DBMS_OUTPUT.put_line ('other');
END;
select * from table(get_a())
在此示例中,在錯誤 ('ab' is not varchar2(1)) 發生之前,第一行已經通過管道傳輸。但我不希望任何東西被退回。有沒有辦法寫取消例外塊中管道的內容?
代碼
uj5u.com熱心網友回復:
否,因為客戶端可能已經使用了該行。
您可以對函式進行編碼,以便它用資料填充本地集合,并且僅在最后決定是否遍歷集合以實際回傳行。這將需要更多記憶體,因為您在回傳之前將整個結果集具體化,并破壞了使用流水線表函式的一些性能優勢。
這樣的事情似乎可以做你想做的事
CREATE or replace FUNCTION get_a
RETURN a_t
PIPELINED
IS
l_a_t a_t := new a_t();
BEGIN
FOR c IN (SELECT '1' a , '2' b FROM DUAL)
LOOP
l_a_t.extend;
l_a_t( l_a_t.count ) := a_r(c.a,c.b);
END LOOP;
FOR a
IN (SELECT 'a2' a,
'b' b
FROM DUAL)
LOOP
l_a_t.extend;
l_a_t( l_a_t.count ) := a_r(a.a,a.b);
END LOOP;
for i in 1 .. l_a_t.count
loop
pipe row( l_a_t(i) );
end loop;
exception
WHEN VALUE_ERROR
THEN
DBMS_OUTPUT.put_line ('VALUE_ERROR');
WHEN OTHERS
THEN
DBMS_OUTPUT.put_line ('other');
END;
/
看到這個 dbfiddle
轉載請註明出處,本文鏈接:https://www.uj5u.com/gongcheng/484734.html
標籤:甲骨文
