%rowtype的几个注意点

本文详细介绍了PL/SQL中%ROWTYPE的使用特点,包括其不保证NOT NULL约束的特性、记录赋值的方法及使用别名的重要性。通过具体示例展示了如何正确使用%ROWTYPE。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、%rowtype只是指明引用的记录的类型,但不保证NOT NULL约束
  
  我们知道使用%type%rowtype可以分别指定引用的字段、记录类型,但其中有一个特别需要注意的地方:
  
  %type%rowtype都不保证NOT NULL约束。例如:
  
  DECLARE
  my_empno emp.empno%TYPE; --emp.empno should not be null
  ...
  BEGIN
  my_empno := NULL; - - this works well
  
  以上这段代码在emp表的empno字段不能为空的情况下依然是可以执行的。
  
  二、%rowtype记录的赋值
  
  用%ROWTYPE作声明的时候是不可以进行初始化赋值的,但是有两种方法可以一次性为所有字段赋值。
  
  方法一:假如两个记录类型的声明引用了同一数据表或游标,那么它们就可以相互赋值,如:
  
  DECLARE
  dept_rec1 dept%ROWTYPE;
  dept_rec2 dept%ROWTYPE;
  CURSOR c1 IS SELECT * FROM dept;
  dept_rec3 c1%ROWTYPE;
  
  BEGIN
  .. . 
  dept_rec1 := dept_rec2 --this works well
  但是,如果一个类型是引用的是数据表而另一个引用的是游标的话,那么,即使它们表现的内容相同,也是不能相互赋值的
  
  dept_rec2 := dept_rec3; - - not allowed
  
  因为此处的dept_rec2引用是表,而dept_rec3引用的是游标,所以即便它们查询的内容一样也
  
  方法二:我们可以使用SELECT或FETCH语句将取得的数据赋给记录。但在表或视图中定义的字段名称顺序要与记录中的名称顺序相同。
  
  DECLARE
  dept_rec dept%ROWTYPE;
  ...
  BEGIN
  SELECT * INTO dept_rec FROM dept WHERE deptno = 30;
  ...
  END; 
  但是,我们不能使用赋值语句来把字段列表中的值赋给记录。所以,下面的语法形式是不允许的:
  
  record_name := (value1, value2, value3, ...); -- not allowed
  
  三、使用别名
  
  从游标中取出的数据,如果游标定义中含有表达式时,我们就需要使用别名才能正确地为%ROWTYPE类型记录赋值:
  
  DECLARE
  CURSOR my_cursor IS
   SELECT sal + NVL(comm, 0) wages, ename FROM emp;
  my_rec my_cursor%ROWTYPE;
  BEGIN
  OPEN my_cursor;
  LOOP
   FETCH my_cursor
   INTO my_rec;
   EXIT WHEN my_cursor%NOTFOUND;
   IF my_rec.wages > 2000 THEN
   INSERT INTO temp VALUES (NULL, my_rec.wages, my_rec.ename);
   END IF;
  END LOOP;
  CLOSE my_cursor;
  END;
  
优化这段代码 CREATE OR REPLACE PROCEDURE ord_dev AS bill_date VARCHAR2(10); v_sql LONG; v_count NUMBER; v_time VARCHAR2(20); v_d VARCHAR2(2); v_m VARCHAR2(2); CURSOR c_tb IS SELECT * FROM b_cur_names; c_row b_cur_names%ROWTYPE; BEGIN EXECUTE IMMEDIATE 'truncate table b_cur_names'; v_sql := 'insert into b_cur_names Select TABLE_NAME from SYS.ALL_TABLES a Where a.owner =upper(''jour1'') And a.table_name Like upper(''om_subscriber_202___'') and Substr(a.table_name,-6) > 202205 order by 1'; COMMIT; EXECUTE IMMEDIATE 'DROP table ord_dev'; ---------------- v_sql := 'insert into ord_dev Select a.order_id,a.done_date, a.cust_id, a.subscriber_ins_id, a.access_num, c.dev_id, c.dev_name, c.corp_org, c.company_name, c.department_code, c.department_name, c.remarks From JOUR1.Om_Subscriber_202301 a Left Join JOUR1.om_order_202301 b On a.order_id = b.order_id Left Join params1.sec_developer c On b.dev_id = c.dev_id Where 1 =2 '; COMMIT; ------------- FOR c_row IN c_tb LOOP v_sql := ' insert into ord_dev Select a.order_id,a.done_date, a.cust_id, a.subscriber_ins_id, a.access_num, c.dev_id, c.dev_name, c.corp_org, c.company_name, c.department_code, c.department_name, c.remarks From JOUR1.Om_Subscriber_' || substr(c_row.table_name, -6) || ' a Left Join JOUR1.om_order_' || substr(c_row.table_name, -6) || ' b On a.order_id = b.order_id Left Join params1.sec_developer c On b.dev_id = c.dev_id Where 1 = 1 And a.access_num Like ''192%'' And a.action = 0'; COMMIT; END LOOP; END;
07-13
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值