oracle 锁定SQL表

5tmbdcev  于 2023-10-16  发布在  Oracle
关注(0)|答案(1)|浏览(115)

假设我有一个过程,它试图根据条件评估将记录一个接一个地插入到单独的表中,并使用sys_refcursor试图取出插入数据的表。
在过程中,我们有DML和DDL命令,如truncate,insert,select,create cursor。
假设多个用户尝试使用相同的参数调用该过程。
问题是,当多个用户试图运行我们正在截断同一个表的过程时,我们最终插入并从中选择,输出数据中可能会出现数据丢失或数据模糊。
想知道过程是否对过程体中提到的表加锁。
现在,为了输出过程的结果集,我将行插入到该表名中,并使用sys_refcursor,我使用下面的代码返回它的内容:

open prc for select * from tablename;

假设我不想将行插入到任何表中。我需要直接将结果集从select语句输出到输出变量。我们如何才能做到这一点?
执行过程调用,对过程体中提到的表加锁,以便其他用户无法访问和修改这些表。
伪代码:

create or replace PROCEDURE PROCEDURE_NAME(var1 in VARCHAR2, var2 in NUMBER, prc out SYS_REFCURSOR)
IS 
  cursor c1 IS 
  select v3 from TABLE_NAME1 where v1 = var1 and v2 = var2; 
  begin
   EXECUTE immediate 'TRUNCATE TABLE AUDIT_TABLE';
   if (var2 = 2)
    then
     for var3 in c1
      loop
         insert into AUDIT_TABLE select col1,col2,col3,col4 
       from              
       (select ROW_NUMBER() OVER(order by row_id) AS num_row, col1, v2, col2, col3, col4 
       from TABLE_NAME1
       where col3 = var3.v3 and v1 = var1 and v2 = var2) a
       inner join 
       (select ROW_NUMBER() OVER(order by row_id) AS num_row, col1, v2, col2, col3, col4 
       from TABLE_NAME1 
       where col3 = var3.v3 and v1 = var1 and v2 = var2) b on
       (b.num_row = a.num_row + 1)
       inner join TABLE_NAME2 c on (a.v2 = c.v2);
        end loop;
       end if;
  open prc for select * from AUDIT_TABLE;
 end;
ebdffaop

ebdffaop1#

我不明白你的程序的目的是什么,也许有更好的解决方案。但是...

  • 每个DML语句都经过优化并转换为某种“字节码”。- 这个“字节码”与数字数据段ID一起工作,而不是与纯表名一起工作。
  • TRUNCATE是DDL语句。它丢弃表的数据段并分配一个新的。为了截断一个表,必须没有任何运行游标,这取决于表的库缓存对象。因此,truncate将等到allDML完成
  • 在truncate和insert之间,其他会话可以截断同一个表。然后,您将有两个会话插入到同一个表中。
  • 虽然有两个会话插入到同一个表中,但它们不会相互干扰。您不提交事务(除了truncate - DDL always commits)。因此,每个会话的游标将只返回自己的会话数据。
  • 注意:你的过程没有COMMIT/ROLLBACK,所以任何连续的TRUNCATE都必须等到对你的过程的第一次调用决定如何处理它自己的数据。

相关问题