zoukankan      html  css  js  c++  java
  • 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 )
    AS
    SELECT dscpt, crt_date FROM t1 WHERE id = @p_id
    RETURN 0
    GO
    通过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 #1


    DESCRIPTION                    CREATED_DATE
    ------------------------------ --------------------
    The value 1                    06-JUL-2013 21:19:45


    1 row selected.


    ResultSet #2


      COUNT(*)
    ----------
             3


    1 row selected.


    SQL> EXEC get_my_results;


    PL/SQL procedure successfully completed.


    ResultSet #1


      COUNT(*)
    ----------
             3


    1 row selected.


    SQL>
    通过RETURN_RESULT过程返回DBMS_SQL的游标时也会存在一些限制和不足。
    3. GET_NEXT_RESULT
    一般来说,我们希望通过客户端应用来处理这些结果集,这可以通过DBMS_SQL包的 GET_NEXT_RESULT过程来解决。
    下例通过DBMS_SQL包来执行该过程。由于过程返回不同记录结构的结果集,我们必须描述这些结果集以便进行处理。这可以通过结果集的列数来进行判断。
    SET SERVEROUTPUT ON
    DECLARE
      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-2013
    The column is COUNT:
    l_count=3


    PL/SQL procedure successfully completed.


    SQL>
    通过过程GET_NEXT_RESULT返回DBMS_SQL中的游标时也会有一些限制和不足。

  • 相关阅读:
    (13)使用Ajax Helper 提高用户体验
    (12)改变图片的大小生成缩略图
    (11)通过表单上传文件
    程序员需要有多懒 ?- cocos2d-x 数学函数、常用宏粗整理
    xCode 4.X 免证书真机发布及调试
    35岁前必须做好的10件事情(转载)
    独自收集Cocos2d提供的字体!共57种(有对照的字体图)
    (10)根据关键字搜索
    tcp拥塞控制
    dpcnv reademe
  • 原文地址:https://www.cnblogs.com/lhdz_bj/p/9049916.html
Copyright © 2011-2022 走看看