zoukankan      html  css  js  c++  java
  • 对象表与PLSQL表类型 比较

    一直以来,对这两种类型一直存有疑惑,现在将自己的一些想法实验记录下来,以便以后查看跟踪改进。

     PLSQL表变量类型

    TYPE typ_id_record IS RECORD(
          gid NUMBER(10),
          gno NUMBER(5),
          co NUMBER(5));
    TYPE typ_id_table1 IS TABLE OF typ_id_record;

     对象表变量类型

    CREATE OR REPLACE TYPE typ_id_object AS OBJECT

                                        (gid NUMBER(10),
                                         gno NUMBER(5),
                                         co NUMBER(5));
    CREATE OR REPLACE TYPE typ_id_table AS TABLE OF typ_id_object;

    1.bulk collect的使用的区别

    PLSQL变量可以直接接收bulk collect,但是对象表变量就必须先进行转换

    如下过程 p_f2中定义了一个对象表变量 tab_ids,直接将查询结果集一次性bulk collect放置到该变量时,会提示:

    ORA-00947: 没有足够的值.如果定义的object变量是单个字段的话,则编译时是提示:
    ORA-00932: 数据类型不一致
    CREATE OR REPLACE PROCEDURE p_f2 IS
       tab_ids typ_id_table;
    BEGIN
       SELECT gp.gid, gp.gno, gp.co   BULK COLLECT
         INTO tab_ids
         FROM p_table_test gp;
    END p_f2;

    解决办法:将object变量进行转换,如下所示:

    CREATE OR REPLACE PROCEDURE p_f2 IS
       tab_ids typ_id_table;
    BEGIN
       SELECT typ_id_object(gp.gid, gp.gno, gp.co)   BULK COLLECT
         INTO tab_ids
         FROM p_table_test gp;
    END p_f2;

     如果采用的是PLSQL表变量,则直接接受查询的结果集就可以了,如下所示:

    CREATE OR REPLACE PROCEDURE p_f4 IS
       tab_ids typ_id_table1;
    BEGIN
       SELECT gp.gid, gp.gno, gp.co BULK COLLECT
         INTO tab_ids
         FROM p_table_test gp;
    END p_f4;
     
    在此,要感谢itpub的windtalker_cs,是他的回答让我明白了一直困扰我的一个问题,之前一直以为如果采用object
    对象表,就无法使用bulk collect批量获取结果集。

    2. 是否可以使用table函数

    函数返回的若是PLSQL类型变量则无法使用table函数,而object类型变量可以使用table函数直接获取函数返回的结果集

    CREATE OR REPLACE FUNCTION p_f2 RETURN typ_id_table IS
       tab_fids typ_id_table := typ_id_table();--object对象表类型
    BEGIN
       FOR i IN 1 .. 100 LOOP
          tab_fids.extend;
          tab_fids(tab_fids.count) := typ_id_object(i, i + 1, i + 2);
       END LOOP;
       RETURN tab_fids;
    END p_f2;
    SQL> SELECT * FROM TABLE(p_f2);
            FID    GNO     CO
    ----------- ------ ------
              1      2      3
              2      3      4
              3      4      5
              4      5      6
              5      6      7
              6      7      8
      ........................
     
    如果函数返回的是record表类型,则无法使用table函数,如下所示:
    CREATE OR REPLACE PACKAGE pkg_f2 IS
       TYPE typ_id_record IS RECORD(
          gid NUMBER(10),
          gno NUMBER(5),
          co  NUMBER(5));
       TYPE typ_id_table1 IS TABLE OF typ_id_record;  --在包头定义PLSQL表类型
       FUNCTION f_f2 RETURN typ_id_table1;
    END pkg_f2;
    CREATE OR REPLACE PACKAGE BODY pkg_f2 IS
       FUNCTION f_f2 RETURN typ_id_table1 IS
          tab_fids typ_id_table1;
       BEGIN
          SELECT rownum, rownum + 1, rownum + 2 BULK COLLECT
            INTO tab_fids
            FROM dual;
          RETURN tab_fids;
       END;
    END pkg_f2;

    SELECT * FROM TABLE(pkg_f2.f_f2);

    提示:ORA-00902:无效数据类型

    注:PLSQL表变量类型必须在schma级进行定义,即必须在包头定义该类型,否则会提示:
    Error: PLS-00642: 在 SQL 语句中不允许使用本地收集类型

  • 相关阅读:
    力扣第945题 使数组唯一的最小增量
    力扣第365题 水壶问题
    力扣面试题40 最小的k个数
    力扣第409题 最长回文串
    力扣第46题 全排列
    力扣第1160题 拼写单词
    力扣面试题01.06 字符串压缩
    力扣第695题 岛屿的最大面积
    树莓派 鼠标自动消失
    树莓派 VNC 远程桌面 同一个桌面
  • 原文地址:https://www.cnblogs.com/lanzi/p/2311431.html
Copyright © 2011-2022 走看看