测试使用集合类型的存储过程

时间:2014-09-25 06:41:16

标签: sql unit-testing collections types oracle11g

PROCEDURE test_max_rows (
    test_out OUT NOCOPY test_col_t,
    test_in  IN         test_t,
    max_rows IN         NUMBER DEFAULT 1000;
)
IS
    CURSOR cur_test ( max_rows IN number ) IS
        SELECT id FROM test_table
        WHERE test_in.key_id = 'ABC'
        AND test_in.curr_nm IS NOT NULL
        AND max_rows < 1 OR ROWNUM <= max_rows;
BEGIN
    OPEN  cur_test( NVL(max_rows, 1000) ) ;
    FETCH cur_test BULK COLLECT INTO test_out;
    CLOSE cur_test ;
END test_max_rows;
/

test_t是一种具有以下定义的对象类型:

test_t

DATE_FROM TIMESTAMP
DATE_TO   TIMESTAMP
CD        col_t
CURR_NM   col_t
VAL       VARCHAR2( 40 )        
KEY_ID    NUMBER

col_t是一个集合类型,具有以下定义:

CREATE OR REPLACE TYPE COL_T IS TABLE OF VARCHAR2(200);

我没有使用过集合,并希望通过创建一个PL / SQL匿名块来测试此proc,以验证它在传递max_rows的不同值时输出正确的行数。

max_rows:500行返回:500

max_rows:10000行返回:10000

max_rows:-1返回的行:全部由光标中的Select Query提取。

我不确定如何在匿名块中传递对象和集合类型的值。感谢您提前提供任何帮助。

1 个答案:

答案 0 :(得分:1)

您只需要声明一个相同类型的集合变量;并声明并填充要传递的对象;

set serveroutput on
DECLARE
  result test_col_t;
  input test_t;
BEGIN
  input := new test_t(null, null, null, new test_col_t(), null, 'ABC');
  test_max_rows(result, input, 50);
  dbms_output.put_line('Rows returned: ' || result.count);
END;
/

您不需要初始化集合,因为它是过程中的OUT参数,但您需要初始化IN参数。我已经离开了你现在不使用null的对象属性。如果您愿意,可以定义NUMBER变量作为max_rows号码传递。

我已经坚持使用ABC ID作为您的查询所需的内容,但在您的对象定义中它是一个数字,所以您要么需要更改类型或将其设置为(并测试)一个数字。如果DEFAULT 1000定义为KEY_ID而不是VARCHAR2,则会按照您显示的定义运行(更正拼写错误,如删除分号NUMBER后)。