不要使用DROP TABLE/CREATE TABLE。请改用DBMS_REDEFINITION。这是我为此功能保留的示例代码的修改版本:
CREATE TABLE my_preexisting_table
( a number,
constraint my_preexisting_table_pk primary key (a) );
GRANT SELECT, UPDATE ON my_preexisting_table TO ont;
-- Start the online redefinition process...
-- First, check whether your table is a candidate for the process
BEGIN
DBMS_REDEFINITION.CAN_REDEF_TABLE('apps','my_preexisting_table',
DBMS_REDEFINITION.CONS_USE_ROWID);
END;
/
-- Create your new table with a new name. This will eventually replace the pre-existing one
--DROP TABLE apps.my_preexisting_table_redef;
CREATE TABLE apps.my_preexisting_table_redef
(
new_column1 NUMBER,
a NUMBER,
new_column2 DATE,
-- Let's change the primary key while we're at it
-- Unfortunately, we have to rename our constraints because they share a global namespace
constraint my_preexisting_table_pk_r primary key (new_column1, a)
)
-- Let's partition the table while we're at it...
PARTITION BY RANGE (new_column2)
INTERVAL (NUMTODSINTERVAL (1,'DAY')) ( partition my_preexisting_table_old values less than (to_date('01-JAN-2000','DD-MON-YYYY') ));
;
-- Takes long if your table is big.
BEGIN
DBMS_REDEFINITION.START_REDEF_TABLE('apps', 'my_preexisting_table','my_preexisting_table_redef',
-- Map columns from the existing table to the new table here
'a new_column1, a a, sysdate new_column2',
dbms_redefinition.cons_use_rowid);
END;
/
DECLARE
num_errors PLS_INTEGER;
BEGIN
DBMS_REDEFINITION.COPY_TABLE_DEPENDENTS('apps', 'my_preexisting_table','my_preexisting_table_redef',
DBMS_REDEFINITION.CONS_ORIG_PARAMS, TRUE, TRUE, TRUE, TRUE, num_errors);
DBMS_OUTPUT.PUT_LINE('Copy depenedent objects: num_errors = ' || num_errors);
END;
-- Make sure there were no problems... or, if there were problems then they were expected. For example,
-- there will be an error listed because it cannot copy the PK constraint from the original table (because we made a new one already)
-- and that's OK.
select * from DBA_REDEFINITION_ERRORS where base_table_name = 'MY_PREEXISTING_TABLE';
BEGIN
DBMS_REDEFINITION.FINISH_REDEF_TABLE('apps', 'my_preexisting_table', 'my_preexisting_table_redef');
END;
/
-- Check out the results.
select * from my_preexisting_table;
-- Verify the grants are still in place...
select * from DBA_TAB_PRIVS where table_Name = 'MY_PREEXISTING_TABLE';
-- Drop our redef table when ready...
DROP TABLE apps.my_preexisting_table_redef;