起因:新开发个存储过程,需要当一个用户调用存储过程操作一行数据时,另外的用户不允许调用过程操作该数据。
解决办法:先将该记录的状态改为处理中,当别的用户看到为处理中时则跳出过程。此时用到了sql%rowcount来判断是否更新了记录的状态
- update table t set t.status = 'processing' where t.id = P_ID and t.status <> 'processing' ;
- if sql%rowcount = 0 then
- return;
- end if;
由于没有用过sql%rowcount,所以特意测试了一下,下面是对sql%rowcount功能的测试:
--先建个测试用表
- create table Z_TEMP
- (
- C1 VARCHAR2(10),
- C2 VARCHAR2(10),
- C3 VARCHAR2(10)
- );
--向表中插入3行测试数据,插入后:
- C1 C2 C3
- ---------- ---------- ----------
- 1
- 2
- 3
写了一段过程来测试:
- declare
- v_n number;
- begin
- update z_temp t set t.c2 = '1' where t.c1 = 1; --更新一行记录 c1 = 1
- v_n := sql%rowcount;
- dbms_output.put_line('第1.0次:' || v_n);
- commit;
- v_n := sql%rowcount;
- dbms_output.put_line('第1.1次:' || v_n);--提交后sql%rowcounty已经为0了
- update z_temp t set t.c2 = '2' where t.c1 = 2; --更新一行记录 c1 = 2
- v_n := sql%rowcount;
- dbms_output.put_line('第2次:' || v_n);
- update z_temp t set t.c2 = '3'; --更新三行记录
- v_n := sql%rowcount;
- dbms_output.put_line('第3次:' || v_n);
- commit;
- end;
- /*输出结果:
- 第1.0次:1
- 第1.1次:0
- 第2次:1
- 第3次:3
- */
执行后表中数据:
- C1 C2 C3
- ---------- ---------- ----------
- 1 3
- 2 3
- 3 3
由此可见sql%rowcount只会记录未被提交的最后一条SQL语句的影响行数。这点很重要,如果想统计多个sql的合计影响行数,就必须在每个sql后面,用一个变量保存当前的sql%rowcount。