2016-11-29 67 views
1

我有這樣一種情況下:甲骨文流水線功能與記錄類型

CREATE OR REPLACE FUNCTION GET_CURSOR_PIPELINE(placeholder IN NUMBER) 
RETURN MY_RECORD_TYPE PIPELINED IS 

TYPE CURSOR_TYPE IS REF CURSOR; 
myCursor CURSOR_TYPE; 

TYPE RECORD_TYPE IS RECORD(
    record_id NUMBER, 
    firstname VARCHAR(50) 
); 
resultSet RECORD_TYPE; 

BEGIN 

OPEN myCursor FOR 

SELECT 1, 'Scott' FROM DUAL 
UNION 
SELECT 2, 'Tiger' FROM DUAL; 

IF (myCursor IS NOT NULL) THEN 

    LOOP 
     FETCH myCursor INTO resultSet; 
     EXIT WHEN myCursor%NOTFOUND; 
     PIPE ROW (MY_RECORD_OBJ(
     resultSet.record_id, 
     resultSet.firstname 
    )); 
    END LOOP; 

    CLOSE myCursor; 

END IF; 

END GET_CURSOR_PIPELINE; 

我的生產代碼及以上樣品之間的唯一區別是,我需要從一個真正的表市值約20場,和不只是來自DUAL的2個領域。

我想避免鍋爐代碼,我必須明確列出所有涉及的領域。上面的功能工作正常,但我必須定義所有涉及的字段3次。當我定義返回類型時,第一時間

CREATE OR REPLACE TYPE MY_RECORD_OBJ AS OBJECT (
RECORD_ID NUMBER, 
FIRSTNAME VARCHAR2(50) 
); 
/
CREATE OR REPLACE TYPE MY_RECORD_TYPE AS TABLE OF MY_RECORD_OBJ; 
/

秒時間當我定義記錄類型(聲明函數的部分),並且第三次當我推物體在管道(PIPE ROW)。

這裏是問題:有沒有辦法避免這種情況,並寫這樣的東西?

PIPE ROW (MY_RECORD_OBJ(resultSet)) 

而且,如果答案是「是的,這是可能的」,如何將代碼看起來適用於一個真實的表時?我應該在某處放置%行類型標籤嗎?

+0

記錄和對象是完全不同的事情。你的'record_type'與你的'my_record_obj'對象或''my_record_type'類型沒有關係。像這樣混淆你的術語很可能會導致混淆,當有人試圖用某個記錄做某件事時(或者反過來)或者奇怪爲什麼'record_type'和'my_record_type'完全不相關的東西。我相信託尼回答了你的問題的實質部分,我只想確保你的術語是清楚的。 –

+0

好的,非常感謝你,你是對的:我弄糊塗了......現在我知道了! :) – serkelion

回答

5

如何:

CREATE OR REPLACE FUNCTION GET_CURSOR_PIPELINE(placeholder IN NUMBER) 
RETURN MY_RECORD_TYPE PIPELINED IS 

myCursor SYS_REFCURSOR; 

resultSet MY_RECORD_OBJ; 

BEGIN 

    OPEN myCursor FOR 
    SELECT MY_RECORD_OBJ(1, 'Scott') FROM DUAL 
    UNION ALL 
    SELECT MY_RECORD_OBJ(2, 'Tiger') FROM DUAL; 

    LOOP 
     FETCH myCursor INTO resultSet; 
     EXIT WHEN myCursor%NOTFOUND; 
     PIPE ROW (resultSet); 
    END LOOP; 

    CLOSE myCursor; 

END GET_CURSOR_PIPELINE; 

您也可以用光標進一步萎縮它LOOP:

CREATE OR REPLACE FUNCTION GET_CURSOR_PIPELINE(placeholder IN NUMBER) 
RETURN MY_RECORD_TYPE PIPELINED IS 

BEGIN 

    FOR myCursor IN 
    (
    SELECT MY_RECORD_OBJ(1, 'Scott') my_record FROM DUAL 
    UNION ALL 
    SELECT MY_RECORD_OBJ(2, 'Tiger') my_record FROM DUAL 
) LOOP 
    PIPE ROW(myCursor.my_record); 
    END LOOP; 

END GET_CURSOR_PIPELINE; 
+0

非常感謝,它好多了! 另一個問題,如果我可能:是不是可以避免在創建MY_RECORD_OBJ實例時分配所有字段?換句話說,有沒有辦法像(只是僞代碼)寫東西:SELECT * INTO MY_RECORD_OBJ(*)? – serkelion

+0

我不這麼認爲,不。 –