前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >PL/SQL --> PL/SQL记录

PL/SQL --> PL/SQL记录

作者头像
Leshami
发布2018-08-07 11:51:32
7180
发布2018-08-07 11:51:32
举报
文章被收录于专栏:乐沙弥的世界乐沙弥的世界

--=======================

-- PL/SQL --> PL/SQL记录

--=======================

PL/SQL记录有着类似于表的数据结构,是一个或多个字段且拥有数据类型的集合体。定义了PL/SQL记录类型之后,可以定义PL/SQL记录变

量。声明一个PL/SQL记录变量相当于定义了多个标量变量,简化了变量的声明,从而大大节省了内存资源。多用于简化单行多列的数据处理。

一、定义PL/SQL记录

1.直接定义PL/SQL记录(首先定义记录类型,类型中包含的记录成员,其次是记录类型变量)

TYPE type_name IS RECORD --type_name用于指定自定义记录类型的名称

(field_name1 datatype1 [NOT NULL] [ := DEFAULT EXPRESSION], --定义记录的成员、数据类型及缺省值

field_name2 datatype2 [NOT NULL] [ := DEFAULT EXPRESSION],

...

field_nameN datatypeN [NOT NULL] [ := DEFAULT EXPRESSION]);

record_name TYPE_NAME; --定义记录变量名record_name

2.使用%rowtype定义PL/SQL记录

使用%rowtype时,记录成员名称和类型与所依赖对象(表,视图,游标)名称和类型完全相同

对于表和视图,游标所有列定义时,使用%rowtype定义将大大节省内存空间

record_name table_name%rowtype --基于不同的对象定义PL/SQL记录,此处为表

record_name view_name%rowtype

reocrd_name cursor_name%rowtype

二、PL/SQL记录的使用

1. SELECT INTO语句中使用

--使用PL/SQL记录变量

undefine no

DECLARE

TYPE emp_record_type IS RECORD

(

name emp.ename%TYPE,

salary emp.sal%TYPE,

dno emp.deptno%TYPE

);

emp_record emp_record_type;

BEGIN --下面的查询到的数据插入到记录变量,注意列之间的顺序与声明顺序保持一致

SELECT ename, sal, deptno INTO emp_record

FROM emp WHERE empno = &no;

dbms_output.put_line(emp_record.name); --输出时仅仅输出记录变量的一个成员emp_record.name

END;

Enter value for no: 7788

SCOTT

--使用PL/SQL记录成员

undefine no

DECLARE

TYPE emp_record_type IS RECORD

(

name emp.ename%TYPE,

salary emp.sal%TYPE,

dno emp.deptno%TYPE

);

emp_record emp_record_type;

BEGIN

SELECT ename, sal INTO emp_record.name, emp_record.salary --此处仅仅使用到了name和salary 成员

FROM emp WHERE empno = &no;

dbms_output.put_line(emp_record.name); --输出时仅仅输出记录变量的一个成员emp_record.name

END;

/

2.INSERT语句中使用记录变量及成员

--使用PL/SQL记录变量

DECLARE

dept_record dept%ROWTYPE;

BEGIN

dept_record.deptno := 50;

dept_record.dname := 'ADMINISTRATOR';

dept_record.loc := 'BEIJING';

INSERT INTO dept VALUES dept_record;

END;

/

scott@ORCL> select * from dept where deptno=50;

DEPTNO DNAME LOC

---------- -------------- -------------

50 ADMINISTRATOR BEIJING

--使用PL/SQL记录成员

scott@ORCL> DECLARE

2 dept_record dept%ROWTYPE;

3 BEGIN

4 dept_record.deptno := 60;

5 dept_record.dname := 'SALES';

6 INSERT INTO dept(deptno, dname) VALUES(dept_record.deptno, dept_record.dname);

7 END;

8 /

PL/SQL procedure successfully completed.

scott@ORCL> select * from dept where deptno in (50,60);

DEPTNO DNAME LOC

---------- -------------- -------------

50 ADMINISTRATOR BEIJING

60 SALES

3.UPDATE语句中使用记录变量及成员

--使用PL/SQL记录变量(使用ROW来更新整行)

DECLARE

dept_record dept%ROWTYPE;

BEGIN

dept_record.deptno := 50;

dept_record.dname := 'SERVICE';

dept_record.loc := 'GuangZhou';

UPDATE dept SET ROW = dept_record WHERE deptno = 50;--注意update时,使用ROW来表示整行

END;

/

--使用PL/SQL记录成员(使用成员记录更新单列或多列)

scott@ORCL> DECLARE

2 dept_record dept%ROWTYPE;

3 BEGIN

4 dept_record.loc:='ShangHai';

5 UPDATE dept SET loc=dept_record.loc WHERE deptno=60;

6 END;

7 /

4.DELETE语句中使用记录变量及成员

DECLARE

dept_record dept%ROWTYPE;

BEGIN

dept_record.deptno:=60;

DELETE FROM dept WHERE deptno=dept_record.deptno;

END;

/

三、PL/SQL记录使用时的几个问题

1.记录成员非空值的问题(非空值应当在初始化时赋值,而不是在使用时赋值)

scott@ORCL> DECLARE

2 TYPE ex_type IS RECORD

3 (col1 NUMBER(3),

4 col2 VARCHAR2(5) NOT NULL);

5 ex_record ex_type;

6 BEGIN

7 ex_record.col1:=15;

ex_record.col1:=TO_CHAR(ex_record.col1);

8 ex_record.col2:='John';

9 DBMS_OUTPUT.PUT_LINE('ex_record.col1 is '||ex_record.col1);

10 DBMS_OUTPUT.PUT_LINE('ex_record.col2 is '||ex_record.col2);

11 END;

12 /

col2 VARCHAR2(5) NOT NULL);

*

ERROR at line 4:

ORA-06550: line 4, column 6:

PLS-00218: a variable declared NOT NULL must have an initialization assignment--错误消息指出非空值应当在初始化时指定

DECLARE

TYPE ex_type IS RECORD(

col1 NUMBER(3),

col2 VARCHAR2(5) NOT NULL := 'John'); --注意对于非空值应当在初始化时赋值,而不是在使用时赋值

ex_record ex_type;

BEGIN

ex_record.col1 := 15;

ex_record.col1 := TO_CHAR(ex_record.col1);

--ex_record.col2:='John';

DBMS_OUTPUT.PUT_LINE('ex_record.col1 is ' || ex_record.col1);

DBMS_OUTPUT.PUT_LINE('ex_record.col2 is ' || ex_record.col2);

END;

ex_record.col1 is 15

ex_record.col2 is John

2.记录变量之间的赋值问题

下面的例子中两个PL/SQL变量name_rec1与name_rec2尽管具有表面上相同的定义,但两者之间不能相互赋值

DECLARE

TYPE ex_type1 IS RECORD(

first_name VARCHAR2(15),

last_name VARCHAR2(30));

TYPE ex_type2 IS RECORD(

first_name VARCHAR2(15),

last_name VARCHAR2(30));

ex_rec1 ex_type1;

ex_rec2 ex_type2;

BEGIN

ex_rec1.first_name := 'Robinson';

ex_rec1.last_name := 'Cheng';

ex_rec2 := ex_rec1; -- 不合理的赋值方式

END;

ex_rec2 := ex_rec1;

*

ERROR at line 13:

ORA-06550: line 13, column 25:

PLS-00382: expression is of wrong type

ORA-06550: line 13, column 3:

PL/SQL: Statement ignored

具有相同的记录类型时,不同记录变量之间可以相互赋值

DECLARE

TYPE ex_type1 IS RECORD(

first_name VARCHAR2(15),

last_name VARCHAR2(30));

ex_rec1 ex_type1;

ex_rec2 ex_type1;

BEGIN

ex_rec1.first_name := 'Robinson';

ex_rec1.last_name := 'Cheng';

ex_rec2 := ex_rec1;

DBMS_OUTPUT.PUT_LINE('ex_rec1 is '||ex_rec1.first_name||' '||ex_rec1.last_name);

DBMS_OUTPUT.PUT_LINE('ex_rec2 is '||ex_rec2.first_name||' '||ex_rec2.last_name);

END;

ex_rec1 is Robinson Cheng

ex_rec2 is Robinson Cheng

3.基于表,基于游标,基于自定义PL/SQL记录的综合使用

DECLARE

CURSOR dept_cur IS --声明游标

SELECT * FROM dept WHERE deptno = 30;

TYPE dept_type IS RECORD( --声明一个自定义的PL/SQL记录类型

deptno NUMBER(2),

dname VARCHAR2(14),

loc VARCHAR2(13));

dept_rec1 dept%ROWTYPE; --声明基于表dept的记录变量

dept_rec2 dept_cur%ROWTYPE; --声明基于游标dept_cur的记录变量

dept_rec3 dept_type; --声明基于自定义dept_type的记录变量

BEGIN

SELECT * INTO dept_rec1 FROM dept WHERE deptno = 30; --将查询的结果插入到基于表dept的记录变量中

OPEN dept_cur;

LOOP

FETCH dept_cur

INTO dept_rec2; --将游标的内容插入到游标记录变量中

EXIT WHEN dept_cur%NOTFOUND;

END LOOP;

dept_rec1 := dept_rec2;

dept_rec3 := dept_rec2;

DBMS_OUTPUT.PUT_LINE(dept_rec1.deptno || ' ' || dept_rec1.dname);

DBMS_OUTPUT.PUT_LINE(dept_rec2.deptno || ' ' || dept_rec2.dname);

DBMS_OUTPUT.PUT_LINE(dept_rec3.deptno || ' ' || dept_rec3.dname);

END;

30 SALES

30 SALES

30 SALES

四、更多参考

有关SQL请参考

SQL 基础--> 子查询

SQL 基础-->多表查询

SQL基础-->分组与分组函数

SQL 基础-->常用函数

SQL 基础--> ROLLUP与CUBE运算符实现数据汇总

SQL基础-->层次化查询(START BY ... CONNECT BY PRIOR)

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2010年12月18日,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档