Oracle12C--记录类型(三十一)

  • 为什么需要记录类型
    • 示例1:定义过程,输出一个雇员的完整信息

 

DECLARE

v_emp_empno emp.empno%TYPE ;

v_emp_ename emp.ename%TYPE ;

v_emp_job emp.job%TYPE ;

v_emp_hiredate emp.hiredate%TYPE ;

v_emp_sal emp.sal%TYPE ;

v_emp_comm emp.comm%TYPE ;

BEGIN

v_emp_empno := &inputempno ;

SELECT ename,job,hiredate,sal,comm INTO

v_emp_ename,v_emp_job,v_emp_hiredate,v_emp_sal,v_emp_comm

FROM emp WHERE empno=v_emp_empno ;

DBMS_OUTPUT.put_line('雇员编号:' || v_emp_empno || ',姓名:' || v_emp_ename || ',职位:' || v_emp_job || ',雇佣日期:' || TO_CHAR(v_emp_hiredate,'yyyy-mm-dd') || ',基本工资:' || v_emp_sal || ',佣金:' || NVL(v_emp_comm,0)) ;

EXCEPTION

WHEN others THEN

RAISE_APPLICATION_ERROR(-20007,'此雇员信息不存在!') ;

END ;

/

输入参数:7369
运行结果:
雇员编号:7369,姓名:SMITH,职位:CLERK,雇佣日期:1980-12-17,基本工资:800,佣金:0

为了保留查询出的多个数值结果,需要定义多个变量。我们需要一个类型包含多个数据。

  • 记录类型
    • Oracle可以使用类似Java类结构体,语法:

TYPE 类型名称 IS RECODE

成员名称数据类型 [[NOT NULL] [:=默认值] 表达式 ],

...
成员名称数据类型 [[NOT NULL] [:=默认值] 表达式 ]

;

定义了新的结构,该结构和基本数据类型一样,需要定义一个此记录类型的变量后,用户才可以使用

注意:编写顺序
在定义的记录类型中,所有数据的保存顺序(数据类型的顺序)为:
ename(VARCHAR2)job(VARCHAR2)hiredate(DATE),sal(NUMBER),comm(NUMBER);
所以在select子句中查询数据时也一定要按照与之一样的顺序,否则建立过程时会出现"ORA-00932"的错误提示

  • 示例1:修改上例,使用记录类型接收查询返回结果

 

DECLARE

v_emp_empno emp.empno%TYPE ;

TYPE emp_type IS RECORD (

ename emp.ename%TYPE ,

job emp.job%TYPE ,

hiredate emp.hiredate%TYPE ,

sal emp.sal%TYPE ,

comm emp.comm%TYPE

) ;

v_emp emp_type ; -- 定义一个指定的复合类型变量

BEGIN

v_emp_empno := &inputempno ;

SELECT ename,job,hiredate,sal,comm INTO v_emp

FROM emp WHERE empno=v_emp_empno ;

DBMS_OUTPUT.put_line('雇员编号:' || v_emp_empno || ',姓名:' || v_emp.ename || ',职位:' || v_emp.job || ',雇佣日期:' || TO_CHAR(v_emp.hiredate,'yyyy-mm-dd') || ',基本工资:' || v_emp.sal || ',佣金:' || NVL(v_emp.comm,0)) ;

EXCEPTION

WHEN others THEN

RAISE_APPLICATION_ERROR(-20007,'此雇员信息不存在!') ;

END ;

/

输入参数:7369
运行结果:
雇员编号:7369,姓名:SMITH,职位:CLERK,雇佣日期:1980-12-17,基本工资:800,佣金:0

问题:使用记录类型和"表%ROWTYPE"有什么区别
上面的程序如果不使用记录类型,直接定义一个
emp表的ROWTYPE对象,不是也可以完成吗?
解答:ROWTYPE固定结构,而TYPE由用户定义结构
使用
ROWTYPE定义的变量其结构完全与表固定,而使用TYPE可以由用户自己来定义结构,在操作上会更加灵活;

  • 示例2:以上是通过查询字段的方式为记录类型赋值,用户也可以自己设置记录类型中的成员数据

DECLARE

TYPE dept_type IS RECORD (

deptno dept.deptno%TYPE := 80, -- 定义默认值

dname dept.dname%TYPE ,

loc dept.loc%TYPE

) ;

v_dept dept_type ;

BEGIN

v_dept.dname := 'MLDN ' ; -- 为记录类型成员赋值

v_dept.loc := '北京' ; -- 为记录类型成员赋值

DBMS_OUTPUT.put_line('部门编号:' || v_dept.deptno || ',名称:' || v_dept.dname || ',位置:' || v_dept.loc) ;

END ;

/

运行结果:
部门编号:80,名称:MLDN ,位置:北京

  • 示例3定义嵌套的记录类型

DECLARE

TYPE dept_type IS RECORD (

deptno dept.deptno%TYPE := 80, -- 定义默认值

dname dept.dname%TYPE ,

loc dept.loc%TYPE

) ;

TYPE emp_type IS RECORD (

empno emp.empno%TYPE ,

ename emp.ename%TYPE ,

job emp.job%TYPE ,

hiredate emp.hiredate%TYPE ,

sal emp.sal%TYPE ,

comm emp.comm%TYPE ,

dept dept_type

) ;

v_emp emp_type ;

BEGIN

SELECT e.empno,e.ename,e.job,e.hiredate,e.sal,e.comm,d.deptno,d.dname,d.loc INTO

v_emp.empno,v_emp.ename,v_emp.job,v_emp.hiredate,v_emp.sal,v_emp.comm,

v_emp.dept.deptno,v_emp.dept.dname,v_emp.dept.loc

FROM emp e,dept d

WHERE e.deptno=d.deptno(+) AND e.empno=7369 ;

DBMS_OUTPUT.put_line('雇员编号:' || v_emp.empno || ',姓名:' || v_emp.ename || ',职位:' || v_emp.job || ',雇佣日期:' || TO_CHAR(v_emp.hiredate,'yyyy-mm-dd') || ',基本工资:' || v_emp.sal || ',佣金:' || NVL(v_emp.comm,0)) ;

DBMS_OUTPUT.put_line('部门编号:' || v_emp.dept.deptno || ',名称:' || v_emp.dept.dname || ',位置:' || v_emp.dept.loc) ;

END ;

/

运行结果:

雇员编号:7369,姓名:SMITH,职位:CLERK,雇佣日期:1980-12-17,基本工资:800,佣金:0

部门编号:20,名称:RESEARCH,位置:DALLAS
分析:
本程序共定义了两个记录类型
dept_typeemp_type,由于emp_type中要定义dept_type记录类型的成员,所以dept_type要在它使用之前定义,而后直接使用emp_type中的dept成员就可以访问dept_type的成员,从而完成操作的嵌套定义。

  • 示例4:增加一条新的记录,利用记录类型保存数据

DECLARE

TYPE dept_type IS RECORD (

deptno dept.deptno%TYPE ,

dname dept.dname%TYPE ,

loc dept.loc%TYPE

) ;

v_dept dept_type ;

BEGIN

v_dept.dname := 'MLDN' ;

v_dept.loc := '北京' ;

v_dept.deptno := 80 ;

INSERT INTO dept VALUES v_dept ; -- 直接插入记录类型的数据

END ;

/

在使用记录类型直接执行更新时,定义的记录类型中的成员顺序要与操作数据表的字段顺序保持一致,否则无法使用

  • 示例5:修改数据,利用记录类型保存数据

DECLARE

TYPE dept_type IS RECORD (

deptno dept.deptno%TYPE ,

dname dept.dname%TYPE ,

loc dept.loc%TYPE

) ;

v_dept dept_type ;

BEGIN

v_dept.dname := 'MLDNJAVA' ;

v_dept.loc := '中国' ;

v_dept.deptno := 80 ;

UPDATE dept SET ROW=v_dept WHERE deptno=v_dept.deptno ;

END ;

/

在使用记录类型更新时,只需要在更新语句后写上ROW,就可以找到dnameloc,但是对于更新主键的限定条件,则还需要在where子句中编写

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值