[英]Can EF6 generate my model objects from a ref cursor returned by an oracle stored procedure
[英]ORACLE: Select from REF CURSOR returned from stored procedure
我有一些返回 REF CURSOR 的過程(我無法更改或避免使用它),但內容可能不同(列數),具體取決於 IN 變量。 傳遞一個值我們將得到兩列,傳遞另一個值我們將得到三列。 我需要使用普通的 SELECT 語句從該游標中獲取結果,所以我最終得到了 PIPLINE FUNCTION。 但我找不到動態更改從游標獲得的列集的解決方案。 有沒有其他方法可以從光標中“選擇”或正確處理動態變化的列集? 非常感謝!
CREATE OR REPLACE package MYPKG as
TYPE REC IS RECORD (
A NUMBER(18),
B DATE,
C NUMBER(18) DEFAULT 1
);
TYPE TCURSOR IS REF CURSOR;
type CUR_TAB is table of REC;
procedure CUR_PROC(CUR OUT TCURSOR, SEL_TYPE IN NUMBER); --some procedure with undefined columns
FUNCTION CUR_TAB_PIPLINED(P_SEL_TYPE IN NUMBER) RETURN MYPKG.CUR_TAB PIPELINED;
END MYPKG;
/
CREATE OR REPLACE package body MYPKG
as
function CUR_TAB_PIPLINED(P_SEL_TYPE IN NUMBER) return MYPKG.CUR_TAB PIPELINED
as
TAB_DATA CUR_TAB;
TEMP_CUR TCURSOR;
begin
MYPKG.CUR_PROC(TEMP_CUR, P_SEL_TYPE);
fetch TEMP_CUR bulk collect into TAB_DATA;
close TEMP_CUR;
pipe row(TAB_DATA(1)); --getting 1 row is enough for example
end;
PROCEDURE CUR_PROC (CUR OUT TCURSOR, SEL_TYPE IN NUMBER) as
BEGIN
IF SEL_TYPE = 1 THEN
OPEN CUR FOR SELECT 1 AS A, SYSDATE AS B FROM dual;
ELSE
OPEN CUR FOR SELECT 1 AS A, SYSDATE AS B, 5 AS C FROM dual;
END IF;
end;
END MYPKG;
/
SELECT * FROM TABLE(MYPKG.CUR_TAB_PIPLINED(1)); --ORA-00942
SELECT * FROM TABLE(MYPKG.CUR_TAB_PIPLINED(2)); --works good
您需要為游標獲取正確的列數:
CREATE OR REPLACE package body MYPKG
as
function CUR_TAB_PIPLINED(P_SEL_TYPE IN NUMBER) return MYPKG.CUR_TAB PIPELINED
as
v_a NUMBER(18);
v_b DATE;
v_c NUMBER(18);
TEMP_CUR TCURSOR;
begin
MYPKG.CUR_PROC(TEMP_CUR, P_SEL_TYPE);
IF p_sel_type = 2 THEN
LOOP
FETCH temp_cur INTO v_a, v_b, v_c;
EXIT WHEN temp_cur%NOTFOUND;
PIPE ROW (REC(v_a, v_b, v_c));
END LOOP;
ELSE
LOOP
FETCH temp_cur INTO v_a, v_b;
EXIT WHEN temp_cur%NOTFOUND;
PIPE ROW (REC(v_a, v_b, 1));
END LOOP;
END IF;
CLOSE TEMP_CUR;
EXCEPTION
WHEN NO_DATA_NEEDED THEN
CLOSE TEMP_CUR;
end;
PROCEDURE CUR_PROC (CUR OUT TCURSOR, SEL_TYPE IN NUMBER) as
BEGIN
IF SEL_TYPE = 1 THEN
OPEN CUR FOR SELECT 1 AS A, SYSDATE AS B FROM dual;
ELSE
OPEN CUR FOR SELECT 1 AS A, SYSDATE AS B, 5 AS C FROM dual;
END IF;
end;
END MYPKG;
/
注意:如果在游標耗盡之前停止調用流水線函數,還需要確保游標已關閉(即捕獲NO_DATA_NEEDED
異常)。
db<> 在這里擺弄
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.