oracle 如何从PLSQL中的函数或PROC返回强类型CURSOR

dsf9zpds  于 2023-08-03  发布在  Oracle
关注(0)|答案(2)|浏览(165)

我现在正在使用PLSQL,在最终成功返回一个弱类型之后,我很想知道如何基于表结构对强类型游标执行此操作,比如说(in)famout employees表。
下面你会发现我想改变和使用的功能。已经开始编辑我的代码在行与TYPE cur_empData IS REF CURSOR RETURN EMPLOYEES%ROWTYPE;
此外,存储的PROC,这应该是调用我的两个测试是附加在最后。
提前感谢和问候

  1. FUNCTION getEmpCursorStrong (
  2. p_startId NUMBER, p_endId NUMBER
  3. )
  4. RETURN EMPLOYEES
  5. IS
  6. TYPE cur_empData IS REF CURSOR RETURN EMPLOYEES%ROWTYPE;
  7. l_sql_query VARCHAR(100);
  8. BEGIN
  9. l_sql_query := 'SELECT * FROM EMPLOYEES';
  10. IF ( p_startId > 0 OR p_endId > 0) THEN
  11. l_sql_query := l_sql_query || ' WHERE employee_id BETWEEN ' || p_startId || ' AND ' || p_endId;
  12. END IF;
  13. OPEN cur_empData FOR
  14. l_sql_query;
  15. RETURN cur_empData;
  16. END getEmpCursorStrong;

字符串
这是调用PROC

  1. PROCEDURE printEmpData (
  2. p_startId NUMBER DEFAULT 0, p_endId NUMBER DEFAULT 0
  3. )
  4. AS
  5. cur_empData SYS_REFCURSOR;
  6. rec_empData EMPLOYEES%ROWTYPE;
  7. BEGIN
  8. dbms_output.put_line('WEAK CURSOR OUTPUT:');
  9. cur_empData := getEmpCursorWeak(p_startId, p_endId);
  10. LOOP
  11. FETCH cur_empData INTO rec_empData;
  12. EXIT WHEN cur_empData%NOTFOUND;
  13. dbms_output.put_line( ' with id: ' || rec_empData.employee_id || ' - ' || rec_empData.LAST_NAME);
  14. END LOOP;
  15. CLOSE cur_empData;
  16. dbms_output.put_line('##########################');
  17. dbms_output.put_line('STRONG CURSOR OUTPUT HERE:');
  18. END printEmpData;

zu0ti5jz

zu0ti5jz1#

不能对强类型游标使用动态SQL。要强制类型匹配,Oracle必须能够描述SQL查询的返回结构,并在解析时(而不是执行时)将其与REF CURSOR定义匹配。它只能用静态SQL来实现这一点。下面是一个例子:

  1. create or replace package testpkg
  2. as
  3. type strongcursortype is ref cursor return dual%ROWTYPE;
  4. end;
  5. /
  6. create or replace function getcursor
  7. return testpkg.strongcursortype
  8. as
  9. strongcursor testpkg.strongcursortype;
  10. begin
  11. open strongcursor for select * from dual;
  12. return strongcursor;
  13. end;
  14. /
  15. create or replace procedure consumecursor
  16. as
  17. strongcursor testpkg.strongcursortype;
  18. resultrow dual%ROWTYPE;
  19. begin
  20. strongcursor := getcursor();
  21. fetch strongcursor into resultrow;
  22. while strongcursor%found
  23. loop
  24. dbms_output.put_line(resultrow.dummy);
  25. fetch strongcursor into resultrow;
  26. end loop;
  27. end;

字符串
现在执行该过程:

  1. begin consumecursor; end;


它工作了,你看到'X'输出。但是如果你想让select * from dual动态化:

  1. create or replace function getcursor
  2. return testpkg.strongcursortype
  3. as
  4. strongcursor testpkg.strongcursortype;
  5. begin
  6. open strongcursor for 'select * from dual';
  7. return strongcursor;
  8. end;
  9. /


在编译时,您将获得:

  1. PLS-00455: cursor 'STRONGCURSOR' cannot be used in dynamic SQL OPEN statement


如果需要动态SQL,请使用弱游标(SYS_REFCURSOR)。这不应该是一个问题--唯一的区别是,强游标在编译时进行验证(如果有问题,则会出错),而弱游标在执行时会在获取时出错。两者都会出错,这只是你什么时候想要出错的问题。

展开查看全部
v1l68za4

v1l68za42#

要基于“EMPLOYEES”表的表结构创建强类型游标,可以使用SYS_REFCURSOR类型沿着游标FOR循环。以下是如何修改函数和调用过程以实现此目的:

修改函数(getEmpCursorStrong):

  1. FUNCTION getEmpCursorStrong (
  2. p_startId NUMBER,
  3. p_endId NUMBER
  4. )
  5. RETURN SYS_REFCURSOR
  6. IS
  7. cur_empData SYS_REFCURSOR;
  8. l_sql_query VARCHAR(100);
  9. BEGIN
  10. l_sql_query := 'SELECT * FROM EMPLOYEES';
  11. IF (p_startId > 0 OR p_endId > 0) THEN
  12. l_sql_query := l_sql_query || ' WHERE employee_id BETWEEN ' || p_startId || ' AND ' || p_endId;
  13. END IF;
  14. OPEN cur_empData FOR l_sql_query;
  15. RETURN cur_empData;
  16. END getEmpCursorStrong;

字符串

修改调用过程(printEmpData)

  1. PROCEDURE printEmpData (
  2. p_startId NUMBER DEFAULT 0,
  3. p_endId NUMBER DEFAULT 0
  4. )
  5. AS
  6. cur_empData SYS_REFCURSOR;
  7. rec_empData EMPLOYEES%ROWTYPE;
  8. BEGIN
  9. dbms_output.put_line('WEAK CURSOR OUTPUT:');
  10. cur_empData := getEmpCursorWeak(p_startId, p_endId);
  11. LOOP
  12. FETCH cur_empData INTO rec_empData;
  13. EXIT WHEN cur_empData%NOTFOUND;
  14. dbms_output.put_line(' with id: ' || rec_empData.employee_id || ' - ' || rec_empData.LAST_NAME);
  15. END LOOP;
  16. CLOSE cur_empData;
  17. dbms_output.put_line('##########################');
  18. dbms_output.put_line('STRONG CURSOR OUTPUT HERE:');
  19. cur_empData := getEmpCursorStrong(p_startId, p_endId); -- Call the strong cursor function
  20. LOOP
  21. FETCH cur_empData INTO rec_empData;
  22. EXIT WHEN cur_empData%NOTFOUND;
  23. dbms_output.put_line(' with id: ' || rec_empData.employee_id || ' - ' || rec_empData.LAST_NAME);
  24. END LOOP;
  25. CLOSE cur_empData;
  26. END printEmpData;


通过这种方式,您将实现:

  1. getEmpCursorStrong函数根据**“EMPLOYEES”表结构返回SYS_REFCURSOR类型的强类型游标。
    1.调用过程
    printEmpData**演示了如何使用弱游标和强游标来获取和显示数据。
    通过这样做,您将能够使用printEmpData过程打印弱类型游标和强类型游标的输出,从而允许您比较结果。

Apsche-Age #postgresql #Ubuntu

展开查看全部

相关问题