PL/SQL 训练02--集合数组

1. 请列举关联数组、嵌套表、VARRAY三种集合类型的区别
区别:
1 关联数组只能在plsql中使用,嵌套表,varray可用于sql中,数据库表中的列
2 嵌套表,varray必须在使用的时候初始化,关联数组在声明时自动完成
3 关联数组是稀疏的,varray是紧凑的,嵌套表开始是紧凑的,删除了其中的元素就不是了
4 嵌套表可以比较是否相等,关联数组、varray不行
5 关联数组无界,varray是有界的,嵌套表可以扩展
6 如果想在一个集合列中保存大量持久数据,唯一的选择就是嵌套表,数据库会在幕后用一个单独的表来保存集合数据

2. 使用TABLE伪函数完成一个集合的排序功能,假定给定一串字符串,比如‘a’,'b','c','f','e','w','h'
A:
CREATE OR REPLACE TYPE LETTER_ORDER IS TABLE OF VARCHAR2(100);

CREATE TABLE  LETTER_ORDERS
(
  MODEL_TYPE  VARCHAR2(12 BYTE),
  LETTER       LETTER_ORDER
) NESTED TABLE LETTER STORE AS LETTER_ORDER_TAB

  insert into LETTER_ORDERS
  values('letter',LETTER_ORDER('a','b','c','f','e','w','h'))
      
select * from table(select cast(LETTER as LETTER_ORDER) from LETTER_ORDERS where MODEL_TYPE='letter') order by 1

a
b
c
e
f
h
w

B:
CREATE OR REPLACE type t_ret_table is table of varchar2(20);
CREATE OR REPLACE function SCOTT.letter_order_t( p_string  t_ret_table)
 return t_ret_table
    as
 --CREATE OR REPLACE type index_tab_array is  VARRAY(20) of varchar2(30);
-- type index_tab_type is VARRAY(50) of varchar2(30);  
--[Error] PLS-00410 (1: 1): PLS-00410: duplicate fields in RECORD,TABLE or argument list are not permitted
--[Error]  (0: 0): PL/SQL: Compilation unit analysis terminated
  --p_string index_tab_array:=index_tab_array('a','b','c','f','e','w','h');
  --p_string_o   index_tab_array:=index_tab_array();
  v_out t_ret_table;--dfine variable
  j NUMBER := 0;
begin  
     v_out :=t_ret_table();--initialize
       FOR i IN 1 .. p_string.COUNT loop
        --dbms_output.put_line('letter_in=='||letter_in(i)); 
        --ORA-06502: PL/SQL: 数字或值错误 : NULL index table key value
        v_out.EXTEND;
        j := j + 1;
        v_out(j):=p_string(i);
     dbms_output.put_line('v_letter_out=='||v_out(j)); 
     end loop; 
     
     return v_out;
end;
/

declare
aa t_ret_table;
v_str t_ret_table:=t_ret_table('a','b','c','f','e','w','h');
begin
aa := letter_order_t(v_str);
for i in 1..aa.count loop
        dbms_output.put_line(aa(i));
end loop;
end;
/

C:
CREATE OR REPLACE TYPE LETTER_ORDER IS TABLE OF VARCHAR2(100);
/

 --可以对集合进行排序,使用table映射成数据库表,然后用内置的名column_value,使用order by排序 
  DECLARE 
       v_letteroder   LETTER_ORDER  := LETTER_ORDER ('a','b','c','f','e','w','h'); 
    BEGIN 
       DBMS_OUTPUT.put_line ('letter order by:'); 
--将集合排列 
       FOR rec IN  (SELECT COLUMN_VALUE letter 
                      FROM TABLE (cast (v_letteroder AS  LETTER_ORDER)) 
                     ORDER BY column_value asc) 
       LOOP 
          DBMS_OUTPUT.put_line (rec.letter); 
       END LOOP; 
    END;  

3. 上次作业所说的订购系统现在需要做一个购物车,使用PLSQL的集合完成这个购物车的设计,包括购物车的查看(遍历打印),添加商品,
删除商品,减少商品购买数量,商品价格汇总等功能,商品信息包括,商品名称,商品所属大类,商品价格,商品购买数量

--购物车表
create table SHOPPING_CART
(  CREATED_BY      VARCHAR2(100) default 'system' not null,
  CREATED_DATE    DATE default sysdate not null,
  UPDATED_BY      VARCHAR2(100) default 'system' not null,
  UPDATED_DATE    DATE default sysdate not null,
  ID_SHOPPING_CART     VARCHAR2(32) default sys_guid() not null,
  STATUS_SHOPPING_CART NUMBER,--1 active,2 inactive ,3 del
  IS_SELECT NUMBER,--0,1
  USER_ID         VARCHAR2(32 BYTE),
  SESSION_ID      VARCHAR2(32 BYTE),
  GOODS_ID        VARCHAR2(40 BYTE),
  GOODS_NAME      VARCHAR2(120 BYTE),
  GOODS_PRICE     NUMBER,
  GOODS_NUMBER    NUMBER,
  GOODS_ATTR_ID   VARCHAR2(40 BYTE),
  GOODS_ATTR      VARCHAR2(40 BYTE),
  PARENT_ID       VARCHAR2(40 BYTE),
  IS_REAL         CHAR(1 BYTE),
  IS_GIFT         CHAR(1 BYTE))

CREATE OR REPLACE PACKAGE SCOTT.load_shopping_cart
IS
   FUNCTION get_shopping_cart (i_userid shopping_cart.user_id%TYPE)
      RETURN shopping_cart.user_id%TYPE;
--procedure add_goods(i_userid shopping_cart.user_id%type,i_goods_id shopping_cart.goods_id%type) ;
-- procedure sub_goods(i_userid shopping_cart.user_id%type,i_goods_id shopping_cart.goods_id%type) ;
-- procedure add_goods_number(i_goods_number number) ;
--procedure sub_goods_number(i_goods_number number) ;
END load_shopping_cart;
/


CREATE OR REPLACE PACKAGE BODY SCOTT.load_shopping_cart
IS
   TYPE shopping_cart_r IS TABLE OF shopping_cart.user_id%TYPE
                              INDEX BY PLS_INTEGER;

   g_config_data   shopping_cart_r;                          --定义一个缓存购物车的集合变量

   FUNCTION get_shopping_cart (i_userid shopping_cart.user_id%TYPE)
      RETURN shopping_cart.user_id%TYPE
   IS
    return_value   shopping_cart.user_id%TYPE; 
      --从数据库中查询i_userid对应的值
      FUNCTION get_config_from_db
         RETURN shopping_cart.user_id%TYPE
      IS
         CURSOR shopping_cart_cur
         IS
            SELECT USER_ID,
                   GOODS_ID,
                   GOODS_NAME,
                   GOODS_PRICE,
                   GOODS_NUMBER,
                   PARENT_ID
              FROM SHOPPING_CART
             WHERE USER_ID = i_userid;

         shopping_cart_rec   shopping_cart_cur%ROWTYPE;
      BEGIN
         OPEN shopping_cart_cur;

         FETCH shopping_cart_cur INTO shopping_cart_rec;

         CLOSE shopping_cart_cur;

         DBMS_OUTPUT.put_line ('log:1');
         RETURN shopping_cart_rec.USER_ID;
      END;
   /*
        --type SHOPPING_CART_type is table of SHOPPING_CART%rowtype index by pls_integer;
       --res shopping_cart_t;
       l_row binary_integer:=1;
       i_userid shopping_cart.user_id%type;
       begin
       i_userid:='2C828F6DFCF31922E053BC02A8C072AA';
           for via in (select *  from shopping_cart where user_id=i_userid) loop
               g_config_datas(l_row):=via;
               l_row:=l_row+1;
           end loop;
           dbms_output.put_line('用户购物车总共'||g_config_datas.count||'行数据 ');
               dbms_output.put_line(g_config_datas.last);
          for i in g_config_datas.first..g_config_datas.last loop
             --dbms_output.put_line(res(i).ename);
           dbms_output.put_line('USER_ID is '||g_config_datas(i).user_id||', GOODS_ID is '||g_config_datas(i).goods_id||', GOODS_NAME is '||
           g_config_datas(i).goods_name||', GOODS_PRICE is '||g_config_datas(i).goods_price||', GOODS_NUMBER is '||g_config_datas(i).goods_number||
           ',PARENT_ID is '||g_config_datas(i).parent_id||',a subtotal of '||g_config_datas(i).goods_price*g_config_datas(i).goods_number);
           end loop;

       end;
           */
   BEGIN
      RETURN g_config_data (i_userid);
   EXCEPTION
      WHEN NO_DATA_FOUND
      THEN
         g_config_data (i_userid) := get_config_from_db ();
         RETURN g_config_data (i_userid);
   END get_shopping_cart;
END load_shopping_cart;
/

--添加商品
CREATE OR REPLACE type       goodsType as object
   (USER_ID  VARCHAR2(32 BYTE),
  GOODS_ID         VARCHAR2(32 BYTE),
  GOODS_NAME          VARCHAR2(32 BYTE),
  GOODS_PRICE          NUMBER,
  GOODS_NUMBER          NUMBER,
  GOODS_ATTR_ID          VARCHAR2(40 BYTE),
  GOODS_ATTR          VARCHAR2(40 BYTE),
  PARENT_ID          VARCHAR2(40 BYTE),
  IS_REAL NUMBER,
  IS_GIFT NUMBER);
/
CREATE OR REPLACE type       goodsTypeProc as table of goodsType;
/

CREATE OR REPLACE procedure SCOTT.add_goods_p
(
     p_add_goods in goodsTypeProc
)
is
begin
   
  --判断数组是否为空
  if p_add_goods.count!=0 then
   
  --循环插入数据
  for i in 1..p_add_goods.count
    loop
      --此处循环插入数据
      insert into shopping_cart(USER_ID,GOODS_ID,GOODS_NAME,GOODS_PRICE,GOODS_NUMBER,GOODS_ATTR_ID,GOODS_ATTR,PARENT_ID,IS_REAL,IS_GIFT) 
      values(p_add_goods(i).USER_ID,p_add_goods(i).GOODS_ID,p_add_goods(i).GOODS_NAME,p_add_goods(i).GOODS_PRICE,
      p_add_goods(i).GOODS_NUMBER,p_add_goods(i).GOODS_ATTR_ID,p_add_goods(i).GOODS_ATTR,p_add_goods(i).PARENT_ID,p_add_goods(i).IS_REAL,p_add_goods(i).IS_GIFT);
      --此处在playsql中查看传入到存储过程的数据(可以在plsql的输出中看到以下输出的内容)
      dbms_output.put_line(p_add_goods(i).USER_ID||p_add_goods(i).GOODS_ID||p_add_goods(i).GOODS_NAME||p_add_goods(i).GOODS_PRICE||
      p_add_goods(i).GOODS_NUMBER||p_add_goods(i).GOODS_ATTR_ID||p_add_goods(i).GOODS_ATTR||p_add_goods(i).PARENT_ID||p_add_goods(i).IS_REAL||p_add_goods(i).IS_GIFT);
      end loop;
      commit;    
      end if ;
end;
/
原文地址:https://www.cnblogs.com/yhq1314/p/10613145.html