2015年05月24日 18:14:42 X-rapido 阅读数:7585 标签: recordvarraytable数据库oracle 更多
个人分类: 数据库
版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/xiaokui_wingfly/article/details/45953633
更早原文1
https://blog.csdn.net/liangweiwei130/article/details/38223319
下面在更早原文1有追加
查看原文:http://www.ibloger.net/article/230.html
1.1 RECORD
定义记录数据类型。它类似于C语言中的结构数据类型(STRUCTURE),PL/SQL提供了将几个相关的、分离的、基本数据类型的变量组成一个整体的方法,即RECORD复合数据类型。在使用记录数据类型变量时,需要在声明部分先定义记录的组成、记录的变量,然后在执行部分引用该记录变量本身或其中的成员。
定义记录数据类型的语法如下:
TYPE RECORD_NAME IS RECORD(
V1 DATA_TYPE1 [NOT NULL][:=DEFAULT_VALUE],
V2 DATA_TYPE2 [NOT NULL][:=DEFAULT_VALUE],
VN DATA_TYPEN [NOT NULL][:=DEFAULT_VALUE]);
1.2 VARRAY
数组是具有相同数据类型的一组成员的集合。每个成员都有一个唯一的下标,它取决于成员在数组中的位置。在PL/SQL中,数组数据类型是VARRAY(variable array,即可变数组)。
定义VARRAY数据类型的语法如下:
TYPE VARRAY_NAMEIS VARRAY(SIZE) OF ELEMENT_TYPE [NOT NULL];
其中,varray_name是VARRAY数据类型的名称,size是正整数,表示可以容纳的成员的最大数量,每个成员的数据类型是element_typeo默认时,成员可以取空值,否则需要使用NOT NULL加以限制。
1.3 TABLE
定义记录表(或索引表)数据类型。它与记录类型相似,但它是对记录类型的扩展。它可以处理多行记录,类似于C语言中的二维数组,使得可以在PL/SQL中模仿数据库中的表。
定义记录表类型的语法如下:
TYPE TABLE NAME IS TABLE OF ELEMENT_TYPE [NOT NULL]
INDEX BY [BINARY_INTEGER|PLS_INTEGER|VARRAY2];
关键字INDEX BY表示创建一个主键索引,以便引用记录表变量中的特定行。
BINARY_INTEGER的说明
如语句:TYPE NUMBERS IS TABLE OF NUMBER INDEX BY BINARY_INTEGER;其作用是,加了”INDEX BYBINARY_INTEGER ”后,NUMBERS类型的下标就是自增长,NUMBERS类型在插入元素时,不需要初始化,不需要每次EXTEND增加一个空间。
而如果没有这句话“INDEXBY BINARY_INTEGER”,那就得要显示对初始化,且每插入一个元素到NUMBERS类型的TABLE中时,都需要先EXTEND。
2.1 创建表结构以及数据准备
--组织机构结构表
CREATE TABLE SF_ORG
(
ORG_ID INT NOT NULL, --组织机构主键ID
ORG_NAME VARCHAR2(50),--组织机构名称
PARENT_ID INT--组织机构的父级
)
--一级组织机构
INSERT INTO SF_ORG(ORG_ID, ORG_NAME, PARENT_ID) VALUES(1, '一级部门1',0);
--二级部门
INSERT INTO SF_ORG(ORG_ID, ORG_NAME, PARENT_ID) VALUES(2, '二级部门2',1);
INSERT INTO SF_ORG(ORG_ID, ORG_NAME, PARENT_ID) VALUES(3, '二级部门3',1);
INSERT INTO SF_ORG(ORG_ID, ORG_NAME, PARENT_ID) VALUES(4, '二级部门4',1);
2.2 RECORD的使用举例
先定义一个只与SF_ORG表中某几个列的数据类型相同的记录数据类型TYPE_ORG_RECORD,然后声明一个该数据类型的记录变量V_ORG_RECORD,最后用替换变量&ORG_ID接受输入的雇员编码,查询并显示该雇员的这几列中的信息。注意,在使用RECORD数据类型的变量时要用“.”运算符指定记录变量名限定词。
一个记录类型的变量只能保存从数据库中查询出的一行记录,如果查询出了多行记录,就会出现错误。
-- RECORD的使用举例
declare
type type_org_record is record(
v_name sf_org.org_name%type,
v_parent sf_org.parent_id%type);
v_record type_org_record;
begin
select org_name, parent_id into v_record from sf_org so
where so.org_id = &org_id;
dbms_output.put_line('部门名称:' || v_record.v_name);
dbms_output.put_line('上级部门编码:' || to_char(v_record.v_parent));
end;
执行时会弹出一个输入框,如下图,执行完毕以后可以在输出中查看效果
2.3 VARRAY的使用举例
先定义一个能保存5个VARCHAR2(25)数据类型的成员的VARRAY数据类型ORG_VARRAY_TYPE,然后声明一个该数据类型的VARRAY变量V_ORG_VARRAY,最后用与ORG_VARRAY_TYPE数据类型同名的构造函数语法给V_ORG_VARRAY变量赋予初值并显示赋值结果。
注意,在引用数组中的成员时.需要在一对括号中使用顺序下标,下标从1开始而不是从0开始。
-- VARRAY的使用举例
declare
type org_varray_type is varray(5) of varchar2(25);
v_arr_set org_varray_type;
begin
v_arr_set := org_varray_type('1','2','3','4','5');
dbms_output.put_line('输出1:' || v_arr_set(1) || '、'|| v_arr_set(2) || '、'|| v_arr_set(3) || '、'|| v_arr_set(4));
dbms_output.put_line('输出2:' || v_arr_set(5));
v_arr_set(5) := '5001';
dbms_output.put_line('输出3:' || v_arr_set(5));
end;
2.4 TABLE使用举例
2.4.1 存储单列多行
这个和VARRAY类似。但是赋值方式稍微有点不同,不能使用同名的构造函数进行赋值。具体的如下:
-- 存储单列多行
declare
type org_table_type is table of varchar2(25)
index by binary_integer;
v_org_table org_table_type;
begin
v_org_table(1) := '1';
v_org_table(2) := '2';
v_org_table(3) := '3';
v_org_table(4) := '4';
v_org_table(5) := '5';
dbms_output.put_line('输出1:' || v_org_table(1) || '、'|| v_org_table(2) || '、'|| v_org_table(3) || '、'|| v_org_table(4)||'、'|| v_org_table(5));
end;
2.4.2 存储多列多行和ROWTYPE结合使用
采用bulkcollect可以将查询结果一次性地加载到collections中。而不是通过cursor一条一条地处理。
-- 存储多列多行和rowtype结合使用
declare
type t_type is table of sf_org%rowtype;
v_type t_type;
begin
select org_id, org_name, parent_id bulk collect into v_type from sf_org where sf_org.org_id <= 3;
for v_index in v_type.first .. v_type.last loop
dbms_output.put_line(v_type(v_index).org_id ||' '|| v_type(v_index).org_name ||' '|| v_type(v_index).parent_id );
end loop;
end;
2.4.3 存储多列多行和RECORD结合使用
采用bulkcollect可以将查询结果一次性地加载到collections中。而不是通过cursor一条一条地处理。
-- 存储多列多行和RECORD结合使用
declare
type test_emp is record
(
c1 sf_org.org_name%type,
c2 sf_org.parent_id%type
);
type t_type is table of test_emp;
v_type t_type;
begin
select org_name, parent_id bulk collect into v_type from sf_org where sf_org.org_id <= 3;
for v_index in v_type.first .. v_type.last loop
dbms_output.put_line(v_type(v_index).c1 || ' ' || v_type(v_index).c2);
end loop;
end;
varry和table集合不能直接对其进行查询。只能对其进行遍历。
在我的Oracle 创建 split 和 splitstr 函数文章中,有包含table的查询示例图:http://blog.csdn.net/xiaokui_wingfly/article/details/45922141
%TYPE说明
为了使一个变量的数据类型与另一个已经定义了的变量(尤其是表的某一列)的数据类型相一致,Oracle提供了%TYPE定义方式。当被参照的那个变量的数据类型改变了之后,这个新定义的变量的数据类型会自动跟随其改变,容易保持一致,也不用修改PL/SQL程序了。当不能确切地知道被参照的那个变量的数据类型时,就只能采用这种方法定义变量的数据类型。
%ROWTYP说明
如果一个表有较多的列,使用%ROWTYPE来定义一个表示表中一行记录的变量,比分别使用%TYPE来定义表示表中各个列的变量要简洁得多,并且不容易遗漏、出错。这样会增加程序的可维护性。
为了使一个变量的数据类型与一个表中记录的各个列的数据类型相对应、一致,Oracle提供%ROWTYPE定义方式。当表的某些列的数据类型改变了之后,这个新定义的变量的数据类型会自动跟随其改变,容易保持一致,也不用修改PL/SQL程序了。当不能确切地知道被参照的那个表的结构及其数据类型时,就只能采用这种方法定义变量的数据类型。
一行记录可以保存从一个表或游标中查询到的整个数据行的各列数据。一行记录的各个列与表中一行的各个列有相同的名称和数据类型。
参考文章:http://blog.csdn.net/liangweiwei130/article/details/38223319
https://blog.csdn.net/xiaokui_wingfly/article/details/45953633
2018年08月02日 23:20:30 鱼丸丶粗面 阅读数:106
版权声明:转载、讨论时,请在明显位置注明出处。 https://blog.csdn.net/qq_34745941/article/details/81368648
CREATE TABLE stu(
ID NUMBER(3) PRIMARY KEY,
xm NVARCHAR2(30)
)
INSERT INTO stu(ID, xm) VALUES(1, '小游子');
INSERT INTO stu(ID, xm) VALUES(2, '小倩子');
单条记录的数据类型定义
v_id System.stu.id%type;
好处:若 id 字段类型改变,v_id 字段类型也会自动跟着改变
所有记录的数据类型定义
v_row System.stu%rowtype;
好处:v_row 中所有的字段类型始终与 stu 表中的字段那类型保持一致。
%type 是声明 单条记录的数据类型,%rowtype 是声明 所有记录的数据类型,如果想 声明多个数据类型(但不是 所有数据类型),该怎么办了?此时就用
record
DECLARE
TYPE type_stu_record IS RECORD(
v_id system.stu.id%TYPE,
v_xm system.stu.xm%TYPE
);
v_stu_record type_stu_record;
BEGIN
SELECT t.id, -- 类型,个数都必须与声明时,保持一致
t.xm
INTO v_stu_record
FROM stu t
WHERE ROWNUM = 1; -- 如果想 赋值多条记录,请看 集合数据类型定义
dbms_output.put_line(v_stu_record.v_id ||' : '||v_stu_record.v_xm);
EXCEPTION WHEN OTHERS THEN
dbms_output.put_line(Sqlerrm);
END;
基本数据类型,
select into
时,只能一条条插入记录
集合数据类型,可使用select bulk collect into
一次性插入所有数据
指定长度的数组,下标从 1 开始。遍历输出所有项
type 数组名 varray(size) of 元素类型 [not null];
size : 数组长度,必填项。
DECLARE
TYPE type_var_stu IS VARRAY(4) OF VARCHAR2(30);
v_arr type_var_stu;
BEGIN
v_arr := type_var_stu('a','b','c','d');
dbms_output.put_line('输出第一个:'||v_arr(3));
v_arr(3) := 'dd'; -- 下标3,必须已存在值,否则报错。
dbms_output.put_line('输出第三个:'||v_arr(3));
FOR v_index IN v_arr.first .. v_arr.last LOOP
-- 循环遍历数组
dbms_output.put_line(v_arr(v_index));
END LOOP;
EXCEPTION WHEN OTHERS THEN
dbms_output.put_line(sqlerrm);
END;
type table_name is table of element_type[not null]
index by [binary_integer|pls_integer|varray2];
index by : 创建一个主键索引,以便引用记录表变量中的特定行。
binary_integer : 下标自增(无需‘初始化’)
DECLARE
TYPE type_table_stu IS TABLE OF VARCHAR2(30)
INDEX BY BINARY_INTEGER;
v_t type_table_stu;
BEGIN
v_t(1) := '1';
v_t(2) := '2';
v_t(3) := '3';
dbms_output.put_line('输出第一个: '||v_t(1));
EXCEPTION WHEN OTHERS THEN
dbms_output.put_line(Sqlerrm);
END;
要插入的列与表数据类型完全一致
DECLARE
TYPE type_table_stu IS TABLE OF system.stu%ROWTYPE;
v_stu type_table_stu;
BEGIN
SELECT t.id, -- 插入的值,个数、类型 都必须和声明时完全一致。
t.xm
BULK COLLECT -- 一次性提取数据至集合内
INTO v_stu
FROM stu t;
FOR v_index IN v_stu.first .. v_stu.last LOOP
dbms_output.put_line(v_stu(v_index).id||' : '||v_stu(v_index).xm);
END LOOP;
EXCEPTION WHEN OTHERS THEN
dbms_output.put_line(Sqlerrm);
END;
DECLARE
TYPE type_record_stu IS RECORD(
v_id system.stu.id%TYPE,
v_xm system.stu.xm%TYPE
);
TYPE type_table_stu IS TABLE OF type_record_stu; -- 将记录作为 table 的数据类型
v_stu type_table_stu;
BEGIN
SELECT t.id,
t.xm
BULK COLLECT
INTO v_stu
FROM stu t;
FOR v_index IN v_stu.first .. v_stu.last LOOP
dbms_output.put_line(v_stu(v_index).v_id||' : '||v_stu(v_index).v_xm);
END LOOP;
EXCEPTION WHEN OTHERS THEN
dbms_output.put_line(Sqlerrm);
END;
https://blog.csdn.net/qq_34745941/article/details/81368648
oracleoracl复合类型详解
知识点:
1,ORACLE 在 PL/SQL 中除了提供象前面介绍的各种类型外,还提供一种称为复合类型的类型---
记录和表.
记录类型类似于C语言中的结构数据类型,它把逻辑相关的、分离的、基本数据类型的变量组成一个整体存储起来,它必须包括至少一个标量型或RECORD 数据类型的成员,称作PL/SQL RECORD 的域(FIELD),其作用是存放互不相同但逻辑相关的信息。在使用记录数据类型变量时,需要先在声明部分先定义记录的组成、记录的变量,然后在执行部分引用该记录变量本身或其中的成员。
定义记录类型语法如下:
Java代码
实例1:
Java代码
实例2:
Java代码
输出如下:
SMITH
CLERK
800
实例3:
Java代码
注意:一个记录类型的变量只能保存从数据库中查询出的一行记录,若查询出了多行记录,就会出现错误。否则会报错:
ORA-01422: 实际返回的行数超出请求的行数
ORA-06512: 在 line 11
第二种复合类型--数组
数据是具有相同数据类型的一组成员的集合。每个成员都有一个唯一的下标,它取决于成员在数组中的位置。在PL/SQL中,数组数据类型是VARRAY。
定义VARRY数据类型语法如下:
Java代码
varray_name是VARRAY数据类型的名称,size是下整数,表示可容纳的成员的最大数量,每个成员的数据类型是element_type。默认成员可以取空值,否则需要使用NOT NULL加以限制。对于VARRAY数据类型来说,必须经过三个步骤,分别是:定义、声明、初始化。
实例1:
Java代码
实例2:
--数组 varray实例
declare
type type_myVarray is varray(3) of Varchar2(30);
v_myvarrayType type_myVarray;
begin
--第一种赋值方法:构造函数赋值
v_myvarrayType := type_myVarray('男人','女人','不男不女');
dbms_output.put_line(v_myvarrayType(1));
dbms_output.put_line(v_myvarrayType(2));
dbms_output.put_line(v_myvarrayType(3));
--第二种赋值方法:一个一个的赋值
select e.ename,e.job,to_char(e.sal) into v_myvarrayType(1),v_myvarrayType(2),v_myvarrayType(3) from scott.emp e where empno = 7369;
--这种方式不行:会报错:---PLS-00642: 在 SQL 语句中不允许使用本地收集类型(这种赋值方式只适应与record类型的变量)
--select e.ename,e.job,to_char(e.sal) into v_myvarrayType from scott.emp e where empno = 7369;
dbms_output.put_line(v_myvarrayType(1));
dbms_output.put_line(v_myvarrayType(2));
dbms_output.put_line(v_myvarrayType(3));
end;
第三种类型:%type
定义一个变量,其数据类型与已经定义的某个数据变量(尤其是表的某一列)的数据类型相一致,这时可以使用%TYPE。
使用%TYPE特性的优点在于:
所引用的数据库列的数据类型可以不必知道;
所引用的数据库列的数据类型可以实时改变,容易保持一致,也不用修改PL/SQL序。
实例:
Java代码
第四种类型:%rowtype
PL/SQL 提供%ROWTYPE操作符, 返回一个记录类型, 其数据类型和数据库表的数据结构相一致。 使用%ROWTYPE特性的优点在于:
所引用的数据库中列的个数和数据类型可以不必知道;
所引用的数据库中列的个数和数据类型可以实时改变,容易保持一致,也不用修改PL/SQL程序。
实例:
Java代码
待续**************************************************************
第五种:更高级的数据类型psql表类型;
在前面我们已经讲解了varray,record类型,可以看出他们都是一维的。下面我们要讲解的是综合上面两种类型的数据类型plsql 表,该表示二维的。可以囊括上面的两种类型。
定义记录表(或索引表)数据类型。它与记录类型相似,但它是对记录类型的扩展。它可以处理多行记录,类似于高级中的二维数组,使得可以在PL/SQL中模仿数据库中的表。
Python正确的学习路线,你一定不知道的薪资翻倍秘
如何从8K提至20K月薪,你要掌握学习那些技能
分享到:
oracle10g 系统自带函数-subStr,sys_connec ... | oracle 视图(view)
评论
https://supanccy2013.iteye.com/blog/1997160