如何使用Oracle过程创建数据流任务来返回数据?

时间:2013-10-17 04:54:30

标签: sql oracle plsql ssis

我有一个SSIS包,它使用数据流任务连接Oracle数据库以运行数据查询并将其输出到平面csv文件。现在我需要将此查询转换为在Oracle过程中获取数据,并从数据流任务中调用此过程。有人为我创建了一个Oracle程序,它基本上返回了一个Cursor。现在有3个问题:

  1. 我是Microsoft SQL专家,但对Oracle知之甚少。
  2. 当我在PL / SQL窗口中运行这样的程序时,它编译正常,但不会像在Microsoft SQL Server中那样返回任何行。那可以吗?

    DECLARE cur MyPackage.cursor_type;
    BEGIN
      MyPackage.GetData(id => 1234, o_cur_out => cur);
    END;
    
  3. 在SSIS中如何调用此过程来获取数据?它只有2个选项“Table or View”& “SQL命令”?

1 个答案:

答案 0 :(得分:1)

运行代码块时,它不会返回任何行。但是,它确实返回cursor指向您可以使用该游标变量cur访问的某些行 - 它是OUT参数,这意味着该过程设置其值,并且当过程完成后,cur光标已准备好进行查询,如下所示:

LOOP
  FETCH cur INTO your_variable1, your_variable2, ..., your_variableN;
  EXIT WHEN cur%NOTFOUND;

  -- process fetched values
END LOOP;

我不确定返回游标OUT参数的过程是否允许您使用SSIS查询数据,遗憾的是我无法自己测试。

我想出了一个可能的解决方案,但它可能过度了。您也可以要求编写该程序的人为您编写PIPELINED函数。这样的函数可以在查询的FROM子句中使用,因此您可以在Oracle数据库中创建一个从该函数获取数据的视图,并在SSIS包中查询该视图。下面是一个示例,也可以在SQLFiddle中找到:http://sqlfiddle.com/#!4/c66c7/1

CREATE TABLE emp (id NUMBER, name VARCHAR2(20));

INSERT INTO emp VALUES (1, 'John');
INSERT INTO emp VALUES (2, 'Jake');

CREATE OR REPLACE TYPE emp_rec_t AS OBJECT (
  id NUMBER,
  name VARCHAR2(20)
);

CREATE OR REPLACE TYPE my_emp_array_t IS TABLE OF emp_rec_t;

CREATE OR REPLACE PROCEDURE my_emp_ref_func(o_emp_cur OUT sys_refcursor)
IS
BEGIN
  OPEN o_emp_cur FOR 'SELECT id, name FROM emp';
END;
/

CREATE OR REPLACE FUNCTION my_emp_func RETURN my_emp_array_t PIPELINED
IS
  v_emp_cur sys_refcursor;
  v_id NUMBER;
  v_name VARCHAR2(20);
BEGIN
  my_emp_ref_func(v_emp_cur);

  LOOP
    FETCH v_emp_cur INTO v_id, v_name;
    EXIT WHEN v_emp_cur%NOTFOUND;

    PIPE ROW (emp_rec_t(v_id, v_name));
  END LOOP;
END;
/

CREATE OR REPLACE VIEW my_emp_cur_view AS
  SELECT id, name
    FROM TABLE(my_emp_func)
;