Oracle PL/SQL开发基础(第十六弹:记录类型)
记录类型有些类似于C语言的结构或者,使用记录可以一次性处理多个类型的值。
记录类型简介
记录类型给了程序员自定义程序结构的能力,这种程序结构是指变量类型的集合,这些变量被组织在一起同一进行管理,是的记录类型有些类似于表的一行。可以把记录类型想象成表的一行记录。
在未使用记录类型之前,我们看个例子,定义多个变量来保存emp表中字段的值:
DECLARE--定义保存字段值的变量v_empno NUMBER;v_ename VARCHAR2 (20);v_job VARCHAR2 (9);v_mgr NUMBER (4);v_hiredate DATE;v_sal NUMBER (7, 2);v_comm NUMBER (7, 2);v_deptno NUMBER (2);
BEGIN--从emp表中取出字段值SELECT empno, ename, job, mgr, hiredate, sal, comm, deptnoINTO v_empno, v_ename, v_job, v_mgr, v_hiredate, v_sal, v_comm, v_deptnoFROM empWHERE empno = :empno;--向emp_copy表中插入变量的值INSERT INTO emp_copy(empno, ename, job, mgr, hiredate, sal, comm,deptno)VALUES (v_empno, v_ename, v_job, v_mgr, v_hiredate, v_sal, v_comm,v_deptno);
EXCEPTION --异常处理块WHEN OTHERSTHENNULL;
END;
这样的写法需要定义多个变量,如果同时对两个以上的表进行操作,会使得变量的定义变得混乱。
如果把所有这些变量考虑为一个单元进行处理,可以将其声明为一个记录类型。使用记录类型修改后:
DECLARE--定义记录类型TYPE t_emp IS RECORD(v_empno NUMBER,v_ename VARCHAR2 (20),v_job VARCHAR2 (9),v_mgr NUMBER (4),v_hiredate DATE,v_sal NUMBER (7, 2),v_comm NUMBER (7, 2),v_deptno NUMBER (2));--声明记录类型的变量emp_info t_emp;
BEGIN--从emp表中取出字段值赋给记录类型SELECT *INTO emp_infoFROM empWHERE empno = :empno;--向emp_copy表中插入记录类型的值INSERT INTO emp_copy VALUES emp_info;
EXCEPTION --异常处理块WHEN OTHERSTHENNULL;
END;
定义记录类型
如:
DECLARE--声明记录类型TYPE emp_rec IS RECORD (dept_row dept%ROWTYPE, --声明来自dept表行的嵌套记录empno NUMBER, --员工编号ename VARCHAR (20), --员工名称job VARCHAR (10), --职位sal NUMBER (7, 2) --薪资);--声明记录类型的变量emp_info emp_rec;
BEGINNULL;
END;
可以在声明的时候对记录类型中的成员进行初始化:
DECLARETYPE emp_rec IS RECORD (empname VARCHAR (12) := '李斯特', --员工名称,初始值李斯特empno NUMBER NOT NULL DEFAULT 7369, --员工编号,默认值7369hiredate DATE DEFAULT SYSDATE, --雇佣日期,默认值当前日期sal NUMBER (7, 2) --员工薪资);--声明emp_rec类型的变量empinfo emp_rec;
BEGINNULL;
END;
记录类型赋值
简单赋值
语法如下:
record_name.field_name := expression;
如:
DECLARETYPE emp_rec IS RECORD (empname VARCHAR (12) := '李斯特', --员工名称,初始值李斯特empno NUMBER NOT NULL DEFAULT 7369, --员工编号,默认值7369hiredate DATE DEFAULT SYSDATE, --雇佣日期,默认值当前日期sal NUMBER (7, 2) --员工薪资);--声明emp_rec类型的变量empinfo emp_rec;
BEGIN--下面的语句为empinfo记录赋值。empinfo.empname:='施密斯';empinfo.empno:=7010;empinfo.hiredate:=TO_DATE('1982-01-01','YYYY-MM-DD');empinfo.sal:=5000;--下面的语句输出empinfo记录的值DBMS_OUTPUT.PUT_LINE('员工名称:'||empinfo.empname);DBMS_OUTPUT.PUT_LINE('员工编号:'||empinfo.empno);DBMS_OUTPUT.PUT_LINE('雇佣日期:'||TO_CHAR(empinfo.hiredate,'YYYY-MM-DD'));DBMS_OUTPUT.PUT_LINE('员工薪资:'||empinfo.sal);
END;
记录类型赋值
除了为单个成员逐个赋值外,还可以为整个记录一次性赋值,最常见的方式是将一个记录类型赋予另一个记录类型的值,如:
DECLARE--定义记录类型TYPE emp_rec IS RECORD (empno NUMBER,ename VARCHAR2 (20));--定义与emp_rec具有相同成员的记录类型TYPE emp_rec_dept IS RECORD (empno NUMBER,ename VARCHAR2 (20));--声明记录类型的变量emp_info1 emp_rec;emp_info2 emp_rec;emp_info3 emp_rec_dept;--定义一个内嵌过程用来输出记录信息PROCEDURE printrec (empinfo emp_rec)ASBEGINDBMS_OUTPUT.put_line ('员工编号:' || empinfo.empno);DBMS_OUTPUT.put_line ('员工名称:' || empinfo.ename);END;
BEGINemp_info1.empno := 7890; --为emp_info1记录赋值emp_info1.ename := '张大千';DBMS_OUTPUT.put_line ('emp_info1的信息如下:');printrec (emp_info1); --打印赋值后的emp_info1记录emp_info2 := emp_info1; --将emp_info1记录变量直接赋给emp_info2DBMS_OUTPUT.put_line ('emp_info2的信息如下:');printrec (emp_info2); --打印赋值后的emp_info2的记录emp_info3:=emp_info1; --此语句出现错误,不同记录类型的变量不能相互赋值
END;
要注意,如果一个记录类型的变量赋给另一个记录类型,两个记录类型必须完全一致,不是光成员一致就行。
但是,使用%ROWTYPE可以根据数据表的行来定义一个记录类型的变量,记录的所有成员是表中的字段列表,可以讲一个以%ROWTYPE定义的记录类型的变量赋给一个与该记录具有完全相同的记录成员的记录变量,如:
DECLARE--定义一个与dept表具有相同列的记录TYPE dept_rec IS RECORD (deptno NUMBER (10),dname VARCHAR2 (30),loc VARCHAR2 (30));--定义基于dept表的记录类型dept_rec_db dept%ROWTYPE;dept_info dept_rec;
BEGIN--使用SELECT语句为记录类型赋值SELECT *INTO dept_rec_dbFROM deptWHERE deptno = 20;--将%ROWTYPE定义的记录赋给标准记录变量dept_info := dept_rec_db;
END;
可以看到,尽管dept_info
和dept_rec_db
并不是相同的dept_rec
类型,但是因为%ROWTYPE的运行机制及dept_rec
中的记录成员与dept表相同,因此赋值是成功的。
如果要清空一个记录类型的 变量,可以简单地为该变量赋一个空的或未初始化的记录类型,即可清空所有的记录成员值。
使用SELECT或FETCH语句赋值
这里先介绍使用SELECT语句赋值。要使用SELECT语句赋值,SELECT语句的选择列表必须要与记录类型的成员个数及类型相匹配,否则Oracle将抛出异常。
如:
DECLARETYPE emp_rec IS RECORD (empno NUMBER (10),ename VARCHAR2 (30),job VARCHAR2 (30));--声明记录类型的变量emp_info emp_rec;
BEGIN--为记录类型赋值SELECT empno,ename,jobINTO emp_infoFROM empWHERE empno = 7369;--输出记录类型的值DBMS_OUTPUT.put_line ( '员工编号:'|| emp_info.empno|| CHR (13)|| '员工姓名:'|| emp_info.ename|| CHR (13)|| '员工职别:'|| emp_info.job);
END;
操纵记录类型
在INSERT语句中使用记录类型
如:
DECLARETYPE dept_rec IS RECORD (deptno NUMBER (2),dname VARCHAR2 (14),loc VARCHAR2 (13));--定义2个记录类型的变量dept_row dept%ROWTYPE;dept_norow dept_rec;
BEGIN--为记录类型赋值dept_row.deptno := 70;dept_row.dname := '工程部';dept_row.loc := '上海';dept_norow.deptno := 80;dept_norow.dname := '电脑部';dept_norow.loc := '北京';--插入%ROWTYPE定义的记录变量到表中INSERT INTO deptVALUES dept_row;--插入普通记录变量的值到表中INSERT INTO deptVALUES dept_norow;--向数据库提交对表的更改COMMIT;
END;
在UPDATE语句中使用记录类型
如:
DECLARETYPE dept_rec IS RECORD ( --定义记录类型deptno NUMBER (2),dname VARCHAR2 (14),loc VARCHAR2 (13));dept_info dept_rec; --定义记录类型的变量
BEGINSELECT *INTO dept_infoFROM deptWHERE deptno = 80; --使用SELECT语句初始化记录类型dept_info.dname := '信息管理部'; --更新记录类型的值UPDATE deptSET ROW = dept_infoWHERE deptno = dept_info.deptno;--在UPDATE中使用记录变量更新表
END;
要注意,SET ROW右边是不能使用子查询的。
在RETURNING子句中使用记录
可以在DML语句中包含一个RETURNING子句,用来返回被UPDATE、DELETE或INSERT操作所影响到的行,通过RETURNING子句,可以将受影响的行保存到一个记录或者是一个记录集合。如:
DECLARETYPE dept_rec IS RECORD ( --定义记录类型deptno NUMBER (2),dname VARCHAR2 (14),loc VARCHAR2 (13));dept_info dept_rec; --定义记录类型的变量dept_returning dept%ROWTYPE; --定义用于返回结果的记录类型
BEGINSELECT *INTO dept_infoFROM deptWHERE deptno = 80; --使用SELECT语句初始化记录类型dept_info.dname := '信息管理部'; --更新记录类型的值UPDATE deptSET ROW = dept_infoWHERE deptno = dept_info.deptno --在UPDATE中使用记录变量更新表,返回受影响的行到记录RETURNING deptno,dname,locINTO dept_returning;dept_info.deptno := 12;dept_info.dname := '维修部';INSERT INTO dept --插入新的部门编号记录,返回受影响的行的记录VALUES dept_infoRETURNING deptno,dname,locINTO dept_returning;DELETE FROM dept --删除现有的部门,返回受影响的行的记录WHERE deptno = dept_info.deptnoRETURNING deptno,dname,locINTO dept_returning;
END;
要注意,记录变量是不允许出现在SELECT列表、WHERE子句、GROUP BY子句或ORDER BY子句中的。
使用嵌套记录
如:
DECLARETYPE dept_rec IS RECORD ( --定义部门记录类型deptno NUMBER (2),dname VARCHAR2 (14),loc VARCHAR2 (13));TYPE emp_rec IS RECORD ( --定义员工记录类型 v_empno NUMBER,v_ename VARCHAR2 (20),v_job VARCHAR2 (9),v_mgr NUMBER (4),v_hiredate DATE,v_sal NUMBER (7, 2),v_comm NUMBER (7, 2),v_dept_rec dept_rec --定义嵌套的员工记录); emp_info emp_rec; --员工记录dept_info dept_rec; --临时部门记录
BEGINSELECT * --从数据库中取出员工部门的记录INTO dept_infoFROM deptWHERE deptno = (SELECT deptnoFROM empWHERE empno = 7369);emp_info.v_dept_rec:=dept_info; --将部门信息记录赋给嵌套的部门记录SELECT empno, ename, job, mgr, --为emp表赋值hiredate, sal, commINTO emp_info.v_empno, emp_info.v_ename, emp_info.v_job, emp_info.v_mgr,emp_info.v_hiredate, emp_info.v_sal, emp_info.v_commFROM empWHERE empno = 7369;--输出嵌套记录的员工所在部门信息DBMS_OUTPUT.PUT_LINE('员工所属部门为:'||emp_info.v_dept_rec.dname);
END;
Oracle PL/SQL开发基础(第十六弹:记录类型)相关推荐
- Oracle PL/SQL开发基础(第十七弹:集合类型)
集合是PL/SQL提供的用来同时处理多个数据的一种数据结构.如果说记录是一个单行多列的数据结构,那么集合就是一种单列多行的数据结构. 集合简介 集合类似于高级语言中的列表或一维数组,主要用来存储具有相 ...
- Oracle PL/SQL开发基础(第三十弹:预定义异常)
无论是预定义错误还是自定义错误,Oracle在内部都会隐含地触发一个错误,每个错误都有一个序号,SQLCODE就是异常的编码,SQLERRM用来获取异常的信息.但是在PL/SQL进行异常处理时,不能直 ...
- 《Oracle PL/SQL开发指南》学习笔记28——源码调试——PL/SQL基础知识(第六部分)
控制结构 1. 条件结构 1)if, elsif和else语句 重要概念: 三值逻辑(Three-Valued Logic) Three-valued logic means basically th ...
- ebs oracle pl sql开发_ORACLEERP开发基础之EBS开发基础
调用会计科目弹性域 1.首先在创建数据表时,添一个字段用来保存会计科目的ID.如:CODE_COMBINATION_ID 2.在FORM相应的数据块增加两个ITEM,用来显示科目NUMBER与DESC ...
- 原创:oracle PL/SQL编程基础 下lt;十二gt;
游标: 游标(cursor)可以被看作指向结果集(a set of rows)中一行的指针(pointer).在oracle数据库中可以使用显示或隐式两种游标. 隐式游标: 在执行一个 sql 语句 ...
- ebs oracle pl sql开发_Oracle EBS Form个性化开发
Oracle EBS Form个性化开发 时间: 2017-03-30 00:55:04 阅读: 728 评论: 收藏: Form个性化开发内容不是很多,在国内的项目上客户化界面上基本用不上,相关开发 ...
- Oracle PL/SQL语句基础学习笔记(上)
PL/SQL是ORACLE对标准数据库语言的扩展,ORACLE公司已经将PL/SQL整合到ORACLE 服务器和其他工具中了,近几年中更多的开发人员和DBA开始使用PL/SQL,本文将讲述PL/SQL ...
- oracle PL/SQL编程基础
目录 1 PL/SQL介绍 1.1 PL/SQL基础结构 1.2 PL/SQL 注释 1.3 PL/SQL常量和变量 1.4条件语句 1.5 循环语句 过完节由于疫情公司没有进行上班,在收拾房屋的过程 ...
- ebs oracle pl sql开发_PL/SQL设置
1.PL/SQL Developer记住登陆密码 再使用PL/SQL Developer时,为了工作方便希望PL/SQL Developer记住登录Oracle的用户名和密码: 设置方法:PL/SQL ...
最新文章
- net-snmp交叉编译出现 undefined reference to dlopen,dlsym,dlclose错误
- map:map是否为空?元素数量?删除元素?
- 【学习笔记】产品成本计划(Product Cost Planning)01
- DbHelper数据库通用类使用方法
- 网友建站经验——(转载)
- 实战快速恢复Exchange 2010误删除的邮箱
- linux驱动基础开发2——linux 驱动开发前奏(模块编程)-转
- C#导入导出Excele数据
- 软件工程|如何写设计文档
- 用华为手机拍照别直接按快门,先打开这个按钮,效果翻倍堪比单反
- 华为光猫 HN8346X6 超级管理员密码获取方法,超简单
- 计算机基础实践教程world,实验16+计算机基础实验报告.docx
- 手机人像摄影入门简易四步法
- [ROS Navigation Tuning Guide]翻译
- jzoj6495 死星 (竞赛图五元环)
- 【MATLAB】使用“蒙特卡罗(Monter Carlo)”算法计算不规则图形的面积
- 为什么使用kbhit后按下键盘无反应?
- 《C语言深度剖析》学习笔记----C语言中的符号
- 简论数控机床的特点及发展趋势
- RK3399 10.0 打开双wifi STA+AP并发
热门文章
- c语言float转bcd码
- 两篇word文档行间距设置的一样但是显示的不一样的解决方法
- Eclipse中java文件图标变成空心J如何解决
- 陈景润是数学改革先锋吗
- 资深项目经理这样做成本控制
- php domdocument soap,在PHP中使用SoapClient从WSDL获取元素
- c语言 截止频率6低通滤波器,如何用c语言实现截止频率为200hz的巴特沃斯低通滤波器...
- springboot基于web的在线问答社区系统设计与实现毕业设计源码061628
- cocos3.5塔防游戏开发---复习cocos2dx结束(明天重启仙剑)
- JSP婚纱影楼管理系统myeclipse开发sql数据库bs框架java编程jdbc