如何取消管道排?
how to cancel Pipe row?
我有管道功能。如果我发现异常,我想 return 没有行。即使在第一次使用管道排后发生异常。
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)) 发生之前,第一行已通过管道传输。但我不想 returned。有没有办法写取消异常块中的管道?
否,因为客户端可能已经使用了该行。
您可以对您的函数进行编码,以便它用数据填充本地集合,并且仅在最后决定是否遍历集合以实际 return 行。这将需要更多内存,因为您在 returning 之前实现了整个结果集,并且会破坏使用流水线 table 函数的一些性能优势。
像这样的东西似乎可以做你想做的事
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;
/
我有管道功能。如果我发现异常,我想 return 没有行。即使在第一次使用管道排后发生异常。
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)) 发生之前,第一行已通过管道传输。但我不想 returned。有没有办法写取消异常块中的管道?
否,因为客户端可能已经使用了该行。
您可以对您的函数进行编码,以便它用数据填充本地集合,并且仅在最后决定是否遍历集合以实际 return 行。这将需要更多内存,因为您在 returning 之前实现了整个结果集,并且会破坏使用流水线 table 函数的一些性能优势。
像这样的东西似乎可以做你想做的事
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;
/