我有一個 PL/SQL 包,其中包含我需要用來驗證結果的程序。
這方面的一個例子可能如下所示:
create or replace PACKAGE MY_TEST
IS
PROCEDURE validate_my_value (p_input_value INT,
p_valid OUT INT);
END;
create or replace PACKAGE BODY MY_TEST
IS
PROCEDURE validate_my_value (p_input_value INT,
p_valid OUT INT)
IS
BEGIN
p_valid := 0;
IF MOD(p_input_value, 2) = 0 THEN
p_valid := 1;
END IF;
END;
END;
我想多次呼叫此程序,并從另一個 PL/SQL 包上的函式回傳 sys_refcursor 中的有效結果。
我有一個示例,我在陣列中收集有效結果,但最終我似乎無法完全正確地獲得輸出格式。
例子:
create or replace PACKAGE MY_TEST_CLIENT
IS
FUNCTION get_validated_values (p_input_begin INT,
p_input_end INT)
RETURN sys_refcursor;
END;
create or replace PACKAGE BODY MY_TEST_CLIENT
IS
TYPE t_num_array IS TABLE OF INTEGER;
FUNCTION get_validated_values (p_input_begin INT,
p_input_end INT)
RETURN sys_refcursor
IS
l_current_value INT;
l_valid INT;
l_result_cursor sys_refcursor;
l_result t_num_array := new t_num_array();
l_count INT := 1;
BEGIN
l_valid := 0;
l_current_value := p_input_begin;
LOOP
MY_TEST.VALIDATE_MY_VALUE(l_current_value, l_valid);
IF l_valid = 1 THEN
l_result.extend();
l_result(l_result.count) := l_current_value;
END IF;
EXIT WHEN l_current_value >= p_input_end;
l_current_value := l_current_value 1;
END LOOP;
IF l_result.count() = 0 THEN
return l_result_cursor;
END IF;
-- TODO convert l_result into l_result_cursor
open l_result_cursor for
-- SELECT * FROM TABLE(l_result); -- This does not work. ORA-22905 and ORA-00642
select 1 from dual; -- Dummy value
return l_result_cursor;
END;
END;
最后,我希望能夠使用如下方式呼叫該方法:
SELECT MY_TEST_CLIENT.get_validated_values(1,10) from DUAL;
因此,基于這里的示例,驗證器應該只產生相等的數字。例如:2、4、6、8 和 10。
我嘗試了類似于Oracle: How to populate/insert row to a Ref Cursor? 但無法讓輸出游標接受結果。
I also tried to loop through the result and create a single SQL statement (select value from dual union ...). However, I had no luck executing the generated SQL statement in a way that left me with a result that could be returned by the sys_refcursor.
Any pointers on how to outputting the result would be appreciated.
uj5u.com熱心網友回復:
@Wernfried 給出了為什么我在最初的問題中遇到問題的線索,并且在資料庫中添加型別有助于完成這項SELET * FROM TABLE(l_result);作業。
create or replace TYPE t_num_array AS TABLE OF INTEGER;
但是,@Justin 的管道建議在這種情況下實際上更有意義。因此,對于流水線輸出,解決方案如下所示:
create or replace PACKAGE BODY MY_TEST_CLIENT2
IS
FUNCTION get_validated_values (p_input_begin INT,
p_input_end INT)
return t_num_array pipelined
IS
l_current_value INT;
l_valid INT;
BEGIN
l_valid := 0;
l_current_value := p_input_begin;
LOOP
MY_TEST.VALIDATE_MY_VALUE(l_current_value, l_valid);
IF l_valid = 1 THEN
pipe row (l_current_value);
END IF;
EXIT WHEN l_current_value >= p_input_end;
l_current_value := l_current_value 1;
END LOOP;
RETURN;
END;
END;
呼叫它會這樣做:
SELECT MY_TEST_CLIENT2.get_validated_values(1,10) from DUAL;
-- TT.T_INTEGER_ARRAY(2, 4, 6, 8, 10)
或者使用@Justing 的建議
SELECT * from table(MY_TEST_CLIENT2.get_validated_values(1,10));
/*
2
4
6
8
10
*/
uj5u.com熱心網友回復:
為了使用,SELECT * FROM TABLE(l_result)您必須將型別創建為資料庫物件,即
CREATE TYPE t_num_array IS TABLE OF INTEGER;
而不是在 PL/SQL 包中定義它。
注意,您可以使用此“單行”獲得相同的結果:
open l_result_cursor for
with t as
(select rownum p_input_begin as r
from dual
connect by rownum <= p_input_end 1)
select r
from t
where mod(r,2)= 0;
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/376679.html
