2016-11-29 82 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

我不这么认为,不。 –