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

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

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

FUNCTION getEmpCursorStrong (
        p_startId NUMBER, p_endId NUMBER
    )
    RETURN EMPLOYEES
    IS
        TYPE cur_empData IS REF CURSOR RETURN EMPLOYEES%ROWTYPE;        
        l_sql_query VARCHAR(100);
    BEGIN
        
        l_sql_query := 'SELECT * FROM EMPLOYEES';

        IF ( p_startId > 0 OR p_endId > 0) THEN
            l_sql_query := l_sql_query || ' WHERE employee_id BETWEEN ' || p_startId || ' AND ' || p_endId;
        END IF;

        OPEN cur_empData FOR
            l_sql_query;

        RETURN cur_empData;
END getEmpCursorStrong;

字符串
这是调用PROC

PROCEDURE printEmpData (
        p_startId NUMBER DEFAULT 0, p_endId NUMBER DEFAULT 0
    )
    AS
        cur_empData SYS_REFCURSOR;
        rec_empData EMPLOYEES%ROWTYPE;
    BEGIN

        dbms_output.put_line('WEAK CURSOR OUTPUT:');
        cur_empData := getEmpCursorWeak(p_startId, p_endId);        

        LOOP
            FETCH cur_empData INTO rec_empData;            
            EXIT WHEN cur_empData%NOTFOUND;
                dbms_output.put_line( ' with id: ' || rec_empData.employee_id || ' - ' || rec_empData.LAST_NAME);
                
        END LOOP;

        CLOSE cur_empData;

        dbms_output.put_line('##########################');
        dbms_output.put_line('STRONG CURSOR OUTPUT HERE:');

    END printEmpData;

zu0ti5jz

zu0ti5jz1#

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

create or replace package testpkg
as
  type strongcursortype is ref cursor return dual%ROWTYPE;
end;
/
create or replace function getcursor
  return testpkg.strongcursortype
as
  strongcursor testpkg.strongcursortype;
begin
  open strongcursor for select * from dual;
  return strongcursor;
end; 
/
create or replace procedure consumecursor
as
  strongcursor testpkg.strongcursortype;
  resultrow dual%ROWTYPE;
begin
  strongcursor := getcursor();
  
  fetch strongcursor into resultrow;
  while strongcursor%found
  loop
    dbms_output.put_line(resultrow.dummy);
    fetch strongcursor into resultrow;
  end loop;
end;

字符串
现在执行该过程:

begin consumecursor; end;


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

create or replace function getcursor
  return testpkg.strongcursortype
as
  strongcursor testpkg.strongcursortype;
begin
  open strongcursor for 'select * from dual';
  return strongcursor;
end; 
/


在编译时,您将获得:

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


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

v1l68za4

v1l68za42#

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

修改函数(getEmpCursorStrong):

FUNCTION getEmpCursorStrong (
    p_startId NUMBER,
    p_endId NUMBER
)
RETURN SYS_REFCURSOR
IS
    cur_empData SYS_REFCURSOR;
    l_sql_query VARCHAR(100);
BEGIN
    l_sql_query := 'SELECT * FROM EMPLOYEES';

    IF (p_startId > 0 OR p_endId > 0) THEN
        l_sql_query := l_sql_query || ' WHERE employee_id BETWEEN ' || p_startId || ' AND ' || p_endId;
    END IF;

    OPEN cur_empData FOR l_sql_query;
    RETURN cur_empData;
END getEmpCursorStrong;

字符串

修改调用过程(printEmpData)

PROCEDURE printEmpData (
    p_startId NUMBER DEFAULT 0,
    p_endId NUMBER DEFAULT 0
)
AS
    cur_empData SYS_REFCURSOR;
    rec_empData EMPLOYEES%ROWTYPE;
BEGIN
    dbms_output.put_line('WEAK CURSOR OUTPUT:');
    cur_empData := getEmpCursorWeak(p_startId, p_endId);        

    LOOP
        FETCH cur_empData INTO rec_empData;            
        EXIT WHEN cur_empData%NOTFOUND;
        dbms_output.put_line(' with id: ' || rec_empData.employee_id || ' - ' || rec_empData.LAST_NAME);                
    END LOOP;

    CLOSE cur_empData;

    dbms_output.put_line('##########################');
    dbms_output.put_line('STRONG CURSOR OUTPUT HERE:');

    cur_empData := getEmpCursorStrong(p_startId, p_endId);  -- Call the strong cursor function

    LOOP
        FETCH cur_empData INTO rec_empData;
        EXIT WHEN cur_empData%NOTFOUND;
        dbms_output.put_line(' with id: ' || rec_empData.employee_id || ' - ' || rec_empData.LAST_NAME);
    END LOOP;

    CLOSE cur_empData;
END printEmpData;


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

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

Apsche-Age #postgresql #Ubuntu

相关问题