隐式数据结果特性将能简化从其他数据库到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中的游标时也会有一些限制和不足。

Oracle12c中PL/SQL(DBMS_SQL)新特性之隐式语句结果(DBMS_SQL.RETURN_RESULT and DBMS_SQL.GET_NEXT_RESULT)的更多相关文章

  1. Oracle12c 中RAC功能增强新特性之ASM&Grid

    1.    自动存储管理(ASM)方面的增强 1.1.   Flex ASM 在典型的网格架构安装中,每个节点有自己的ASM实例运行并扮演该节点上数据库的存储容器的角色,对这种安装配置,存在单点失败的 ...

  2. Oracle12c中性能优化增强新特性之数据库智能闪存

    智能闪存功能最初在XD中引入.从Oracle11.2.0.2开始,除了用于XD存储,还可用于任何闪盘.Oracle12c中,不需卷管理器就可以使用闪盘. 1.  简介 智能闪存在solaris和lin ...

  3. Oracle12c中容错&性能新特性之表空间组

    1.        简介 表空间组可以使用户消耗来自多个表空间的临时表空间.表空间组有如下特点: 1)      至少包含一个表空间.表空间组中包含的最大表空间数没有限制. 2)      和表空间共 ...

  4. Oracle中PL/SQL的执行部分和各种流程控制

    Oracle中PL/SQL的执行部分和异常部分 一.PL/SQL的执行部分. 赋值语句. 赋值语句分两种,一种是定义一个变量,然后接收用户的IO赋值:另一种是通过SQL查询结果赋值. 用户赋值举例: ...

  5. Oracle中PL/SQL简介、基本语法以及数据类型

    Oracle中PL/SQL简介.基本语法以及数据类型 一.PL/SQL简介. Oracle PL/SQL语言(Procedural Language/SQL)是结合了结构化查询和Oracle自身过程控 ...

  6. 简单理解ECMAScript2015中的箭头函数新特性

    箭头函数(Arrow functions),是ECMAScript2015中新加的特性,它的产生,主要有以下两个原因:一是使得函数表达式(匿名函数)有更简洁的语法,二是它拥有词法作用域的this值,也 ...

  7. Java 9中的 9个 新特性

    Java 9 中的 9个 新特性 java 7 2011发布,Java 8 2014发布,java9发布于2017年9月21日. 你可能已经听说过 Java 9 的模块系统,但是这个新版本还有许多其它 ...

  8. 【译】.NET 5. 0 中 Windows Form 的新特性

    自从 Windows Form 在 2018 年底开源并移植到 .NET Core 以来,团队和我们的外部贡献者都在忙于修复旧的漏洞和添加新功能.在这篇文章中,我们将讨论 .NET 5.0 中 Win ...

  9. Java 8 新特性1-函数式接口

    Java 8 新特性1-函数式接口 (原) Lambda表达式基本结构: (param1,param2,param3) -> {代码块} 例1: package com.demo.jdk8; i ...

随机推荐

  1. 《java入门第一季》之面向对象(谈谈接口)

    软件中有接口,这里的接口与硬件中的接口还是有很大区别的. 这里介绍接口不考虑JDK8的新特性(JDK8开始接口里面可以有非抽象方法了,介绍JDK8新特性可能要到整个第一季写完吧!) 还是直接进入接口的 ...

  2. Ubuntu快速截图

    以前截图,都是按Print键全屏截图,Alt+Print可以截当前的窗口.同时把系统自带的截图工具放到面板上,用的时候点击一下,再选择区域截图,很是不方便.不过,Ubuntu允许自己定义快捷键.要自己 ...

  3. Android万能的指示器

    说到 ViewPager 指示器,想必大家都不陌生,绝大部分应用中都有这个.使用频率非常之高.但系统对它的支持并不好,自带的 PagerTabStrip 和 PagerTitleStrip 太弱,很难 ...

  4. infiniDB的论坛

    http://infinidb.co/community 包括了基本的内容. 安装目录?

  5. AngularJS进阶(二十)HTML5实现获取地理位置信息并定位功能

    HTML5实现获取地理位置信息并定位功能 注:请点击此处进行充电! 前言 这篇文章主要介绍了HTML5实现获取地理位置信息并定位功能,本文讲解了原生HTML5.百度地图.谷歌地图等三种获取理位置信息并 ...

  6. LAV Filter 源代码分析 4: LAV Video (2)

    上一篇文章分析了LAV Filter 中的LAV Video的两个主要的类:CLAVVideo和CDecodeThread.文章:LAV Filter 源代码分析 3: LAV Video (1) 在 ...

  7. leetCode之旅(12)-反转二叉树

    背景描述 Homebrew 是 OS X 平台上的包管理工具.用其官网的话说就是: the missing package manager for OS X | OS X 平台遗失的包管理器. 相信在 ...

  8. ARP 协议抓包分析

    ARP(Address Resolution Protocol)- 地址解析分析 ARP 协议是根据IP地址获取物理地址的一个TCP/IP协议. 当PC1 想与 PC2 进行通信时,需要同时知道PC2 ...

  9. Java IO学习--(一)概述

    在这一小节,我会试着给出Java IO(java.io)包下所有类的概述.更具体地说,我会根据类的用途对类进行分组.这个分组将会使你在未来的工作中,进行类的用途判定时,或者是为某个特定用途选择类时变得 ...

  10. Java小技巧输出26个英文字母

    相信有的童鞋写到过与字母有关的小东西,是否有写过全部的字母呢?26个这么多字母,一个个打会疯掉.所有咱们可以用一个小技巧使用for循环帮我们把26个字母自动搞出来,大家来瞅一眼把! 使用Java遍历2 ...