truncate好像是ddl语言吧,能在过程中直接调用吗?

解决方案 »

  1.   

    用动态sql就可以,我上面只是写一个大概意思
      

  2.   

    这两个存储过程在共以个JOB里面调,就可以避免了
      

  3.   

    好像没办法避免,为什么不使用global temporary table 呢?
    不影响你处理数据,也不用考虑清空数据,
      

  4.   

    global temporary table?不考虑清空数据?那下一批的数据来的时候,global temporary table 会怎么处理上次的数据?
    我的oracle是8.0.6
      

  5.   

    Oracle806肯定不能考虑临时表的方案我想搞清楚的是抛开IT,光从业务逻辑来说,如果两次操作之间的时间间隔不足以完成所有的操作,那怎么处理?想通了这点问题就好解决了。我想不外乎两种选择:
    1、允许后面的新数据等待:那就采用在一个任务中对整个表锁定,用LOCK TABLE ... IN EXCLUSIVE MODE,在一个任务完成以前,其他的任务处于等待状态。
    2、不允许新数据等待:那我建议采用每个任务对一个独立的表操作,也就是说每次新数据是插入前建立一个新表(表名可以采用一个序列来区分),插入数据到新表中,在这个表中进行数据操作,完成以后直接删除这个表。一点注意事项:在插入新数据的时候不要建立任何索引,以保证插入的速度最快;在数据插入完成以后,建立合理的索引,以提高数据操作的速度。这些都可以用动态SQL来完成。
      

  6.   

    我在论坛上查了加锁和解锁的贴子。看到关于解锁似乎都是用断掉当前session来做。有没有方法做到:等存储过程执行到一定阶段后,把锁定的那些表解锁?另外,如果我把给一组表加锁的工作放在一个存储过程中完成。通过crontab调用执行这个存储过程的任务,如果上一次加锁后,表还没有解锁,下一次调用这个存储过程时,还能给表加上锁吗?
      

  7.   

    解锁可以通过commit or rollback来解除。
    如果你加的是EXCLUSIVE 锁,下一次是加不上了的
      

  8.   

    我想也是,我用的EXCLUSIVE 锁,如果下一次是加上了的不就死锁了吗?
    谢谢penitent(只取一瓢)。对了,我一看到你的这个名字,就情不自禁的想到了七星瓢虫,呵呵!
      

  9.   

    不过,我还是对你的问题很奇怪
    1、truncate很快,不可能执行10分钟。
    2、insert隐式加了EXCLUSIVE行级锁,truncate虽然是ddl,但在这里,
    确实不能提交改变并删除的。它会返回资源忙的异常。还有必要加表级EXCLUSIVE锁吗???以上各位,我不明白,给我一个解释
      

  10.   

    大哥教训的是!我的oracle基本概念比较缺乏:( 
    我正在努力学习,看来还是不够用功:)
    我的进程是用crontab调用的,每隔一定时间调用一次,不是同一个进程。我上面说的不清楚。
      

  11.   

    大哥教训的是!我的oracle基本概念比较缺乏:( 
    我正在努力学习,看来还是不够用功:)
    我的进程是用crontab调用的,每隔一定时间调用一次,不是同一个进程。我上面说的不清楚。
      

  12.   

    做了一下测试,用lock table不行
    1、create table test (id number(2);
    2、session1: 
       insert into test values (1);
       commit;
    3、session2:
       lock table test in exclusive mode;
    4、session1:
       insert into test values (2);  
       -- waitint until lock released from S2
    5、session2:
       truncate table test;
       返回ERROR at line 1:
           ORA-00054: resource busy and acquire with NOWAIT specified
       但是因为truncate带了默认的commit,所以锁被释放
    6、session1:
       step4中的insert完成
       commit;
    7、在任意session中
       select * from test;
       返回id=1, id=2两条记录另外用操作系统文件做标记也不是很好,我还是认为每个session生成一个独立的表处理比较容易控制。
      

  13.   

    做了一下测试,用lock table不行
    1、create table test (id number(2);
    2、session1: 
       insert into test values (1);
       commit;
    3、session2:
       lock table test in exclusive mode;
    4、session1:
       insert into test values (2);  
       -- waitint until lock released from S2
    5、session2:
       truncate table test;
       返回ERROR at line 1:
           ORA-00054: resource busy and acquire with NOWAIT specified
       但是因为truncate带了默认的commit,所以锁被释放
    6、session1:
       step4中的insert完成
       commit;
    7、在任意session中
       select * from test;
       返回id=1, id=2两条记录
    结论:因为truncate table不管是否成功都会commit,所以锁被解除,导致truncate过程实际上什么都没有做,这不符合你的要求另外用操作系统文件做标记也不是很好,我还是认为每个session生成一个独立的表处理比较容易控制。
      

  14.   

    做了一下测试,用lock table不行
    1、create table test (id number(2);
    2、session1: 
       insert into test values (1);
       commit;
    3、session2:
       lock table test in exclusive mode;
    4、session1:
       insert into test values (2);  
       -- waitint until lock released from S2
    5、session2:
       truncate table test;
       返回ERROR at line 1:
           ORA-00054: resource busy and acquire with NOWAIT specified
       但是因为truncate带了默认的commit,所以锁被释放
    6、session1:
       step4中的insert完成
       commit;
    7、在任意session中
       select * from test;
       返回id=1, id=2两条记录另外用操作系统文件做标记也不是很好,我还是认为每个session生成一个独立的表处理比较容易控制。
      

  15.   

    想想用系统文件也没有什么不好其实可以用更简单的:用操作系统环境变量,你是在unix环境下,那可以在每次job开始的时候把某个自定义的环境变量设为一个固定值,完成以后再复原。当另一个job开始的时候检查该环境变量,如果未复原,那就跳过本次执行。原理和用操作系统文件一样明白了吗?
      

  16.   

    想想用系统文件也没有什么不好其实可以用更简单的:用操作系统环境变量,你是在unix环境下,那可以在每次job开始的时候把某个自定义的环境变量设为一个固定值,完成以后再复原。当另一个job开始的时候检查该环境变量,如果未复原,那就跳过本次执行。原理和用操作系统文件一样明白了吗?