不要做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;
是否有一個理由,爲什麼你不按照程序如Oracle文檔中給出? [在線重新定義表格](http://docs.oracle.com/cd/B19306_01/server.102/b14231/tables.htm#ADMIN01514) –
不,沒有理由。我給出的答案是作品,但是如果我偏離最佳做法的方式可能導致實際問題,我將非常感謝您的意見。 –
順便說一句...你給的鏈接是非常必要的,我在我的答案中做了什麼。另外,我並不認爲它是最佳實踐的處方,而更多是端到端的流程示例。你有什麼特別反對嗎? –