Oracle重命名在事务中使用的表或视图

时间:2016-06-08 22:12:32

标签: oracle

在未完成的事务中重命名查询所使用的表时,oracle数据库中会发生什么?查询会失败吗? 视图是一样的吗? 如果删除在查询中使用的表未完成,该怎么办?

1 个答案:

答案 0 :(得分:0)

答案是肯定的,您可以在交易期间重命名表或视图。它不会为正在进行的交易生成任何错误

以下是测试此内容的脚本

set serveroutput on;

drop procedure test_rename_read
/

drop sequence seq_test_rename_pk
/

truncate table test_rename
/

drop table test_rename cascade constraints
/

truncate table test_rename_newname
/

drop table test_rename_newname cascade constraints
/

create table   test_rename(
 attribute_pk   integer
,text           varchar2(300)
)
/


alter table test_rename add constraint test_rename_pk primary key(attribute_pk)
/ 

create sequence seq_test_rename_pk  start with 1 increment by 1 minvalue 1 maxvalue 9999999 nocycle
/

--insert dummy data
begin
   for i in 1..1000 loop
   insert into test_rename
     values (  seq_test_rename_pk.nextval -- no duplicates here
              ,'Test '||i);
   end loop;
end;
/


create or replace procedure test_rename_read ( p_instance_no in number)
is

  cursor cu_test_rename is
    select * from test_rename;

  c_rec_test cu_test_rename%rowtype; 

begin
  dbms_application_info.set_module('test_rename_read instance '||to_char(p_instance_no), null);

  open cu_test_rename;  
  fetch cu_test_rename into c_rec_test;  

  DBMS_LOCK.sleep(seconds => 30); --sleep for 30 seconds to make sure that the other sessions 

  while cu_test_rename%found loop
   -- read the cursor until the end
   fetch cu_test_rename into c_rec_test;  
  end loop;

exception
  when others then
     raise_application_error(-20000, 'Non expected error: '||sqlerrm);
end;
/


--- run the parallel test
declare
  l_max_concurrent_procs integer := 10;
  l_instno               integer := 1;  
  l_jobno                number;
begin
   -- 10 CONCURRENT SESSIONS THAT READ THE TABLE
   for i in 1..l_max_concurrent_procs loop
       dbms_job.submit( job => l_jobno
                       ,what =>    'declare '
                                || '  v_text    varchar2(200) := ''instance number '||to_char(i)||''';'
                                || 'begin '
                                || ' test_rename_read( '
                                || '    p_instance_no  => '||to_char(i)
                                || ' );'           
                                || 'end; ' 
                       ,next_date => sysdate + (1/24/60/60)* 10 -- execute in 10 seconds from now   
                       ,interval  => null
                       ,no_parse  => true
                       ,instance  => l_instno
                       ,force     => true
                       );
   end loop;
   -- RENAME THE TABLE
   dbms_job.submit( job => l_jobno
                  ,what =>   'begin '                  
                          || ' execute immediate ''rename test_rename to test_rename_newname''; '
                          || '      /*  test_rename_read */ ' -- to easily track all jobs
                          || 'end; ' 
                 ,next_date => sysdate + (1/24/60/60)* 10 -- execute in 10 seconds from now   
                 ,interval  => null
                 ,no_parse  => true
                 ,instance  => l_instno
                 ,force     => true
                 );   

commit;
end;
/ 

和一些有用的查询

-- check the jobs
select * from dba_jobs where what like '% test_rename_read%'
/

-- parallel sessions
select * from v$session where module like 'test_rename_read%'
/
-- waits for the parallel sessions
select * from V$SESSION_WAIT where sid in (select sid from v$session where module like 'test_rename_read%')
/

-- locked objects
select l.sid, l.id1, o.OBJECT_NAME
  from v$lock l
  join  dba_objects o
    on  (o.object_id = l.id1)
 where l.sid in (select sid from v$session where module like 'test_rename_read%')
   and l.TYPE='TM'
/




--- remove jobs in case of error
DECLARE
jobid NUMBER;

CURSOR c1
IS
SELECT job
FROM dba_jobs
WHERE what like '% test_rename_read%';
BEGIN
OPEN c1;

LOOP
FETCH c1
INTO jobid;

EXIT WHEN c1%NOTFOUND;
DBMS_JOB.broken (jobid, TRUE);
COMMIT;
DBMS_JOB.remove (jobid);
COMMIT;
END LOOP;

CLOSE c1;
END;
/