我有一个SSIS包,它使用数据流任务连接Oracle数据库以运行数据查询并将其输出到平面csv文件。现在我需要将此查询转换为在Oracle过程中获取数据,并从数据流任务中调用此过程。有人为我创建了一个Oracle程序,它基本上返回了一个Cursor。现在有3个问题:
当我在PL / SQL窗口中运行这样的程序时,它编译正常,但不会像在Microsoft SQL Server中那样返回任何行。那可以吗?
DECLARE cur MyPackage.cursor_type; BEGIN MyPackage.GetData(id => 1234, o_cur_out => cur); END;
在SSIS中如何调用此过程来获取数据?它只有2个选项“Table or View”& “SQL命令”?
答案 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)
;