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; /