具有记录类型的Oracle流水线功能

时间:2016-11-29 16:22:33

标签: oracle plsql pipeline

我遇到如下情况:

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;
/

第二次当我定义RECORD类型(声明函数的部分)时,第三次当我在管道中推送对象时(PIPE ROW) 。

这是问题:有没有办法避免这种情况,只写这样的东西?

PIPE ROW (MY_RECORD_OBJ(resultSet))

此外,如果答案是“是的,那是可能的”,那么在应用于真实表时代码会如何?我应该在某处放置%rowtype 标签吗?

1 个答案:

答案 0 :(得分:6)

这个怎么样:

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;

您还可以使用游标FOR 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;