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;
/
PL/SQL 训练02--集合数组的更多相关文章
- PL/SQL 训练10--io及文件操作
多数程序只需要通过SQL和底层数据库进行交互--有些情况,不可避免的还是会有一些场景,需要从PL/SQL给外部环境发送信息--或是从一些外部的源读入信息 --这节课介绍下面这些内置包 dbms_out ...
- PL/SQL 训练13--plsql 优化
--数据缓存技术 --PGA和SGA---SGA:系统全局区域--PGA:Process Global Area是为每个连接到Oracle的用户进程保留的内存. ---PLSQL从PGA获取信息的速度 ...
- PL/SQL 训练05--游标
--隐式游标--通过一个简单的SELECT ...INTO 语句提取一行数据,并放在一个局部变量中,最简单获取数据的途径 --显示游标--可以在声明单元明确的声明一个查询,这样可以在一个或多个程序中打 ...
- oracle学习之路(四) ---------PL/SQL 表,二维数组(TABLE)
LOB类型 ORACLE提供了LOB (Large OBject)类型.用于存储大的数据对象的类型.ORACLE眼下主要支持BFILE, BLOB, CLOB 及 NCLOB 类型. NCLOB 存储 ...
- pl/sql programming 02 创建并运行plsql代码
/* * chap 02 * ------------------------------------------------- */ create or replace function wordc ...
- PL/SQL 训练12--动态sql和绑定变量
--什么是动态SQL?动态PL/SQL--动态SQL是指在运行时刻才构建执行的SQL语句--动态PL/SQL是指整个PL/SQL代码块都是动态构建,然后再编译执行 --动态SQL来可以用来干什么? - ...
- PL/SQL 训练11--包
--所谓包,就是把一组PL/SQL的代码元素组织在一个命名空间下.--一种可以把程序或者其他的PL/SQL元素比如游标.类型.变量的组织结构在一起的结构(包括逻辑结构和物理结构)--包提供了非常重要的 ...
- PL/SQL 训练08--触发器
--什么是触发器呢?--一触即发,某个事件发生时,执行的程序块?--数据库触发器是一个当数据库发生某种事件时作为对这个事件的响应而执行的一个被命名的程序单元 --适合场景--对表的修改做验证--数据库 ...
- PL/SQL 训练04--事务
--pl/sql通过SQL和ORACLE数据库紧密的整合在一起--在pl/sql中可以执行任何操作语句(DML语句),包括INSERT,UPDATE,DELETE,MERGE,也包括查询语句--可否执 ...
随机推荐
- phpstrom ctrl+s无法上传的问题 解决
首先这个不教你怎么配置同步FTP,这个教程网上太多了. 主要是配置好了上传,上传的好好的,突然某一天不能上传了,或者配置好了上传不了. 我遇到的问题是,如果你没有点击Use this server a ...
- 【LABVIEW到C#】4》String的操作之Search and Replace.vi
C#封装如下: public class SearchAndRepalce : Darrenstring { public bool replaced; private string stringou ...
- jquery attr与prop的区别与联系
最近开发中发现用attr无法设置checkbox的选中事件,在网上找了下说要用prop,所以总结下两者的区别. 1.操作的对象不同 attr:操作的是HTML文档节点属性 prop:操作的是js对象属 ...
- Ceph配置项动态变更机制浅析
转自:https://www.ustack.com/blog/ceph%e9%85%8d%e7%bd%ae%e9%a1%b9%e5%8a%a8%e6%80%81%e5%8f%98%e6%9b%b4%e ...
- 21-THREE.JS 将法线矢量映射到RGB颜色的材质
<!DOCTYPE html> <html> <head> <title></title> <script src="htt ...
- Spring Batch教程
Spring Batch系列总括 : http://www.cnblogs.com/gulvzhe/archive/2011/12/20/2295090.html
- JS 页面加载触发事件 document.ready和onload的区别
document.ready和onload的区别——JavaScript文档加载完成事件页面加载完成有两种事件: 一是ready,表示文档结构已经加载完成(不包含图片等非文字媒体文件): 二是onlo ...
- oracle如何去除字段的回车换行符
oracle如何去除字段的回车换行符? 可以用trim也可以用replace.区别在于,trim处理字符串两端,而replace中间也可以处理. trim select '全世界无产者 ' || '联 ...
- [置顶]
Android 关于BottomDialogSheet 与Layout擦出爱的火花?
今天上班做那个类似于ios拍照的那种效果图 就是个垂直布局然后里面textview+分割线+textview+button 当然也可以用button+分割线+button 方法有很多,选择适合自己的就 ...
- HAWQ取代传统数仓实践(十六)——事实表技术之迟到的事实
一.迟到的事实简介 数据仓库通常建立于一种理想的假设情况下,这就是数据仓库的度量(事实记录)与度量的环境(维度记录)同时出现在数据仓库中.当同时拥有事实记录和正确的当前维度行时,就能够从容地首先维护维 ...