Oracle12c中PL/SQL(DBMS_SQL)新特性之隐式语句结果(DBMS_SQL.RETURN_RESULT and DBMS_SQL.GET_NEXT_RESULT)

前端之家收集整理的这篇文章主要介绍了Oracle12c中PL/SQL(DBMS_SQL)新特性之隐式语句结果(DBMS_SQL.RETURN_RESULT and DBMS_SQL.GET_NEXT_RESULT)前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

隐式数据结果特性将能简化从其他数据库到Oracle12c存储过程迁移。1. 背景T-sql中允许查询结果的隐式返回。例如:下面T-sql存储过程隐式返回查询结果。CREATE PROCEDURE Get_Results( @p_id  int )ASSELECT dscpt,crt_date FROM t1 WHERE id = @p_idRETURN 0GO通过DBMS_sql包中的RETURN_RESULT过程,Oracle 12c目前支持类似的功能。这在实施迁移时非常有用。2. RETURN_RESULT不是显式定义参照游标(ref cursor)输出参数,DBMS_sql包中的RETURN_RESULT过程允许结果隐式传出,看下例。CREATE table t1 (  id           NUMBER,  dscpt  VARCHAR2(30),  crt_date DATE);INSERT INTO t1 VALUES (1,‘The value 1‘,SYSDATE-2);INSERT INTO t1 VALUES (2,‘The value 2‘,SYSDATE-1);INSERT INTO t1 VALUES (3,‘The value 3‘,SYSDATE);COMMIT;现在我们创建一个过程来返回一个或多个结果集。CREATE OR REPLACE PROCEDURE get_results (p_id IN NUMBER DEFAULT NULL)AS  l_cursor_1 SYS_REFCURSOR;  l_cursor_2 SYS_REFCURSOR;BEGIN  IF p_id IS NOT NULL THEN    OPEN l_cursor_1 FOR      SELECT dscpt,crt_date      FROM   t1      WHERE  id = p_id;    DBMS_sql.RETURN_RESULT(l_cursor_1);  END IF;  OPEN l_cursor_2 FOR    SELECT COUNT(*)    FROM   t1;  DBMS_sql.RETURN_RESULT(l_cursor_2);END;/我们从sql*plus中执行该过程时,将会自动显式显示语句结果。sql> EXEC get_results(1);PL/sql procedure successfully completed.ResultSet #1DESCRIPTION                    CREATED_DATE------------------------------ --------------------The value 1                    06-JUL-2013 21:19:451 row selected.ResultSet #2  COUNT(*)----------         31 row selected.sql> EXEC get_my_results;PL/sql procedure successfully completed.ResultSet #1  COUNT(*)----------         31 row selected.sql>通过RETURN_RESULT过程返回DBMS_sql的游标时也会存在一些限制和不足。3. GET_NEXT_RESULT一般来说,我们希望通过客户端应用来处理这些结果集,这可以通过DBMS_sql包的 GET_NEXT_RESULT过程来解决。下例通过DBMS_sql包来执行该过程。由于过程返回不同记录结构的结果集,我们必须描述这些结果集以便进行处理。这可以通过结果集的列数来进行判断。SET SERVEROUTPUT ONDECLARE  l_sql_cursor    PLS_INTEGER;  l_ref_cursor    SYS_REFCURSOR;  l_return        PLS_INTEGER;  l_col_cnt       PLS_INTEGER;  l_desc_tab      DBMS_sql.desc_tab;  l_count         NUMBER;  l_dscpt   t1.dscpt%TYPE;  l_crt_date  t1.crt_date%TYPE;BEGIN  -- 执行过程  l_sql_cursor := DBMS_sql.open_cursor(treat_as_client_for_results => TRUE);  DBMS_sql.parse(c             => l_sql_cursor,                 statement     => ‘BEGIN get_results(1); END;‘,                 language_flag => DBMS_sql.native);  l_return := DBMS_sql.execute(l_sql_cursor);  -- 循环遍历每个结果集  LOOP    -- 获取下个结果集    BEGIN      DBMS_sql.get_next_result(l_sql_cursor,l_ref_cursor);    EXCEPTION      WHEN NO_DATA_FOUND THEN        EXIT;    END;    -- 检查结果集列数    l_return := DBMS_sql.to_cursor_number(l_ref_cursor);    DBMS_sql.describe_columns (l_return,l_col_cnt,l_desc_tab);    l_ref_cursor := DBMS_sql.to_refcursor(l_return);    -- 根据列数处理结果集    CASE l_col_cnt      WHEN 1 THEN        DBMS_OUTPUT.put_line(‘The column is COUNT:‘);        FETCH l_ref_cursor        INTO  l_count;        DBMS_OUTPUT.put_line(‘l_count=‘ || l_count);        CLOSE l_ref_cursor;      WHEN 2 THEN        DBMS_OUTPUT.put_line(‘The columns are DSCPT and CRT_DATE:‘);        LOOP          FETCH l_ref_cursor          INTO  l_dscpt,l_crt_date;          EXIT WHEN l_ref_cursor%NOTFOUND;          DBMS_OUTPUT.put_line(‘l_dscpt=‘ || l_dscpt || ‘  ‘ ||                               ‘l_crt_date=‘ || TO_CHAR(l_crt_date,‘DD-MON-YYYY‘));        END LOOP;        CLOSE l_ref_cursor;      ELSE        DBMS_OUTPUT.put_Line(‘I wasn‘‘t expecting that!‘);    END CASE;  END LOOP;END;/The columns are DSCPT and CRT_DATE:l_dscpt=The value 1  l_crt_date=06-JUL-2013The column is COUNT:l_count=3PL/sql procedure successfully completed.sql>通过过程GET_NEXT_RESULT返回DBMS_sql中的游标时也会有一些限制和不足。

猜你在找的Oracle相关文章