The APPS user can be used to do this, it has the EXECUTE_CATALOG_ROLE and all the privileges needed.
For information on the DBMS_REDEFINITION built in package see Oracle Database PL/SQL Packages and Types Reference.
Note that the single procedure DBMS_REDEFINITION.REDEF_TABLE cannot be used to partition a table. This procedure provides a single interface that integrates several redefinition steps including the CAN_REDEF_TABLE Procedure, the START_REDEF_TABLE Procedure, the COPY_TABLE_DEPENDENTS Procedure and the FINISH_REDEF_TABLE Procedure. This procedure can change data storage properties and compress type, but cannot be used to partition a table.
1. Always ensure that there is a method in place to revert to a non- partitioned table if serious problems occur.
This will normally be a backup. In addition to this, it will be useful to identify and test removing the partitioning (and reverting to non-partitioned) using Online Table Redefinition. Keeping the original table and indexes (now with the interim names) for a while after the process may assist with this, although they will need truncating before reverting.
If there are errors or issues during the redefinition process, the procedure DBMS_REDEFINITION.abort_redef_table can be used to terminate the redefinition process, leaving the original and interim tables in their initial state.
See Oracle Database Administrator's Guide > 20 Managing Tables > Redefining Tables Online > Aborting Online Table Redefinition and Cleaning Up After Errors.
2. Verify that the table can be redefined online by invoking the CAN_REDEF_TABLE procedure.
In this case AP_INVOICES_ALL has a pseudo primary key (index AP_INVOICES_U1) so the redefinition method can be "by key" (DBMS_REDEFINITION.CONS_USE_PK).
"By key" is the preferred and default method, but will not be suitable for all tables. It requires a primary key or pseudo-primary key (unique key with all component columns having NOT NULL constraints). If there is no suitable primary key (or pseudo primary key) then use the method "by rowid" (DBMS_REDEFINITION.CONS_ USE_ROWID).
BEGIN
DBMS_REDEFINITION.CAN_REDEF_TABLE(uname => 'AP',
tname => 'AP_INVOICES_ALL',
options_flag => DBMS_REDEFINITION.CONS_USE_PK);
END;
/
It should be possible to redefine almost all Oracle E-Business Suite tables (as they were initially installed/seeded).
3. Create an interim table AP.AP_INVOICES_ALL_INT with the new partitioning structure.
Include the constraints. This should be created in the same schema as the table being redefined. Take care that the table has exactly the same properties (storage, tablespace etc) as the original.
In this example, constraints (e.g. NOT NULL) have been created. However, they can be omitted and copied from the original table using procedure COPY_TABLE_DEPENDENTS (see below).
CREATE TABLE "AP"."AP_INVOICES_ALL_INT"
(INVOICE_ID NUMBER(15,0) NOT NULL,
LAST_UPDATE_DATE DATE NOT NULL,
LAST_UPDATED_BY NUMBER(15,0) NOT NULL,
VENDOR_ID NUMBER(15,0) NOT NULL,
INVOICE_NUM VARCHAR2(50 BYTE) NOT NULL,
SET_OF_BOOKS_ID NUMBER(15,0) NOT NULL,
INVOICE_CURRENCY_CODE VARCHAR2(15 BYTE) NOT NULL,
PAYMENT_CURRENCY_CODE VARCHAR2(15 BYTE) NOT NULL,
PAYMENT_CROSS_RATE NUMBER NOT NULL,
.....
RELATIONSHIP_ID NUMBER(15,0),
PO_MATCHED_FLAG VARCHAR2(1 BYTE),
VALIDATION_WORKER_ID NUMBER(15,0))
....
PARTITION BY HASH (invoice_id) PARTITIONS 8;
COMMENT ON COLUMN AP.AP_INVOICES_ALL_INT.CUST_REGISTRATION_CODE IS 'Customer legal registration code';
COMMENT ON COLUMN AP.AP_INVOICES_ALL_INT.CUST_REGISTRATION_NUMBER IS 'Customer legal registration number';
Also create indexes on the interim table with the new partitioning structure.
CREATE INDEX AP.AP_INVOICES_INT_N1 ON AP.AP_INVOICES_ALL_INT (BATCH_ID) .... LOCAL;
CREATE INDEX AP.AP_INVOICES_INT_N10 ON AP.AP_INVOICES_ALL_INT (PO_HEADER_ID) ....;
CREATE INDEX AP.AP_INVOICES_INT_N11 ON AP.AP_INVOICES_ALL_INT (PROJECT_ID, TASK_ID) .... LOCAL;
CREATE INDEX AP.AP_INVOICES_INT_N12 ON AP.AP_INVOICES_ALL_INT (VOUCHER_NUM) ....;
CREATE INDEX AP.AP_INVOICES_INT_N13 ON AP.AP_INVOICES_ALL_INT (DOC_SEQUENCE_VALUE) ....;
CREATE INDEX AP.AP_INVOICES_INT_N14 ON AP.AP_INVOICES_ALL_INT (GLOBAL_ATTRIBUTE1) .... LOCAL;
CREATE INDEX AP.AP_INVOICES_INT_N15 ON AP.AP_INVOICES_ALL_INT (PAID_ON_BEHALF_EMPLOYEE_ID) .... LOCAL;
CREATE INDEX AP.AP_INVOICES_INT_N16 ON AP.AP_INVOICES_ALL_INT (WFAPPROVAL_STATUS) .... LOCAL;
CREATE INDEX AP.AP_INVOICES_INT_N17 ON AP.AP_INVOICES_ALL_INT (VALIDATION_REQUEST_ID) ....;
CREATE INDEX AP.AP_INVOICES_INT_N18 ON AP.AP_INVOICES_ALL_INT (VENDOR_ID, INVOICE_NUM, ORG_ID, EARLIEST_SETTLEMENT_DATE, INVOICE_DATE) ....;
CREATE INDEX AP.AP_INVOICES_INT_N19 ON AP.AP_INVOICES_ALL_INT (CREDITED_INVOICE_ID) ....;
CREATE INDEX AP.AP_INVOICES_INT_N2 ON AP.AP_INVOICES_ALL_INT (VENDOR_ID, INVOICE_TYPE_LOOKUP_CODE, PAYMENT_STATUS_FLAG) .... LOCAL;
CREATE INDEX AP.AP_INVOICES_INT_N20 ON AP.AP_INVOICES_ALL_INT (INVOICE_NUM, PARTY_ID, PAYMENT_STATUS_FLAG) ....;
CREATE INDEX AP.AP_INVOICES_INT_N21 ON AP.AP_INVOICES_ALL_INT (ORG_ID, APPROVAL_READY_FLAG, VALIDATION_REQUEST_ID, PAYMENT_STATUS_FLAG, HISTORICAL_FLAG) .... LOCAL;
CREATE INDEX AP.AP_INVOICES_INT_N3 ON AP.AP_INVOICES_ALL_INT (PAYMENT_STATUS_FLAG, PAY_GROUP_LOOKUP_CODE, ORG_ID) .... LOCAL;
CREATE INDEX AP.AP_INVOICES_INT_N5 ON AP.AP_INVOICES_ALL_INT (INVOICE_DATE, ORG_ID) .... LOCAL;
CREATE INDEX AP.AP_INVOICES_INT_N6 ON AP.AP_INVOICES_ALL_INT (INVOICE_NUM) ....;
CREATE INDEX AP.AP_INVOICES_INT_N7 ON AP.AP_INVOICES_ALL_INT (VENDOR_SITE_ID) .... LOCAL;
CREATE INDEX AP.AP_INVOICES_INT_N8 ON AP.AP_INVOICES_ALL_INT (CREATION_DATE) .... LOCAL;
CREATE UNIQUE INDEX AP.AP_INVOICES_INT_U1 ON AP.AP_INVOICES_ALL_INT (INVOICE_ID) .... LOCAL;
CREATE UNIQUE INDEX AP.AP_INVOICES_INT_U3 ON AP.AP_INVOICES_ALL_INT (DOC_SEQUENCE_ID, DOC_SEQUENCE_VALUE) ....;
Note that if indexes are not created on the interim table (just copied from the original table as part of the COPY_TABLE_DEPENDENTS procedure) then the indexes will not be partitioned, they will be global non partitioned.
Grants (privileges) and triggers do not need to be created, because they can be created when dependent objects are copied below (using the COPY_TABLE_DEPENDENTS procedure).
4. Start the redefinition process by calling START_REDEF_TABLE
Note : For large tables, the performance of the redefinition step can be significantly improved by forcing parallel DDL, DML and parallel query e.g. :
ALTER SESSION FORCE PARALLEL DDL;
ALTER SESSION FORCE PARALLEL DML;
ALTER SESSION FORCE PARALLEL QUERY;
Remember to revert after online redefinition (if necessary) if the same session will be used for subsequent actions.
BEGIN
DBMS_REDEFINITION.START_REDEF_TABLE(uname => 'AP',
orig_table => 'AP_INVOICES_ALL',
int_table => 'AP_INVOICES_ALL_INT',
options_flag => DBMS_REDEFINITION.CONS_USE_PK);
END;
/
Note that the copy_vpd_opt parameter does not need to be specified.
There are no VPD policies on the AP_INVOICES_ALL. In Oracle E-Business Suite the VPD policies are on either views or synonyms.
Editioning policies (ZD_SEED), where present, are on table# views (e.g. AP_EXPENSE_REPORTS_ALL#). Multi organization (ORG_SEC) policies, where present are almost always on SYNONYMs, although there are a few on views.
There are a few other sundry policies on synonyms and views.
5. Register the indexes as dependent.
The indexes will not be copied using the COPY_TABLE_DEPENDENTS procedure, the indexes from the interim table will be used instead. However, the indexes on the interim table need to be registered as dependent:
BEGIN
DBMS_REDEFINITION.REGISTER_DEPENDENT_OBJECT(uname => 'AP',
orig_table => 'AP_INVOICES_ALL',
int_table => 'AP_INVOICES_ALL_INT',
dep_type => DBMS_REDEFINITION.CONS_INDEX,
dep_owner => 'AP',
dep_orig_name => 'AP_INVOICES_N1',
dep_int_name => 'AP_INVOICES_INT_N1');
DBMS_REDEFINITION.REGISTER_DEPENDENT_OBJECT(uname => 'AP',
orig_table => 'AP_INVOICES_ALL',
int_table => 'AP_INVOICES_ALL_INT',
dep_type => DBMS_REDEFINITION.CONS_INDEX,
dep_owner => 'AP',
dep_orig_name => 'AP_INVOICES_N2',
dep_int_name => 'AP_INVOICES_INT_N2');
6. Copy the dependent objects from the original table to the interim table using the COPY_TABLE_DEPENDENTS procedure
This includes triggers, materialized view logs, grants (privileges) and statistics.
Constraints and indexes do not need to be copied, these have already been created on the main table.
Errors should not be ignored.
DECLARE
l_num_errors PLS_INTEGER;
BEGIN
DBMS_REDEFINITION.COPY_TABLE_DEPENDENTS(uname => 'AP',
orig_table => 'AP_INVOICES_ALL',
int_table => 'AP_INVOICES_ALL_INT',
copy_indexes => 0,
copy_triggers => TRUE, -- default
copy_constraints => FALSE,
copy_privileges => TRUE, -- default
ignore_errors => FALSE, -- default
num_errors => l_num_errors,
copy_statistics => TRUE,
copy_mvlog => TRUE);
END;
/
7. Perform Intermediate Synchronization (if necessary)
After the redefinition process has been started by calling START_REDEF_TABLE and before FINISH_REDEF_TABLE has been called, a large number of DML statements might have been executed on the original table.
If this is the case, then it is recommended that the interim table is periodically synchronized with the original table using the SYNC_INTERIM_TABLE procedure.
Calling this procedure reduces the time taken by FINISH_REDEF_TABLE to complete the redefinition process. There is no limit to the number of times that SYNC_INTERIM_ TABLE can be called.
8. Execute the FINISH_REDEF_TABLE procedure to complete the redefinition of the table.
BEGIN
DBMS_REDEFINITION.FINISH_REDEF_TABLE(uname => 'AP',
orig_table => 'AP_INVOICES_ALL',
int_table => 'AP_INVOICES_ALL_INT',
dml_lock_timeout => NULL); -- default
END;
/
Use a value of NULL (default) for the dml_lock_timeout parameter so that the procedure FINISH_REDEF_TABLE does not time out.
During this procedure, the original table is locked in exclusive mode for a very short time, independent of the amount of data in the original table. However, FINISH_REDEF_TABLE will wait for all pending DML to commit before completing the redefinition.
9. Wait for any long-running queries against the interim table to complete, and then drop the interim table.
If the interim table is dropped while there are active queries running against it, an ORA-08103 error ("object no longer exists") may be encountered.
However, the interim table can be kept for a short while (and truncated) as part of a reversion strategy (see step 1).
10. Re-compilation and Refresh
Partitioning a previously non-partitioned table in Oracle E-Business Suite should not cause any other dependent objects (including PL/SQL and triggers) to become invalidated. However, a check for invalid objects should still be carried out. Re-compile any packages or triggers that have become invalid.
After redefining a table that has materialized view logs, the subsequent refresh of any dependent materialized views must be a complete refresh.
11. Testing
The whole process must be tested thoroughly, including:
1. Performance of affected online and batch processes (regression testing).
2. Functionality of affected online and batch processes (regression testing).
3. Performance (elapsed time and workload) during the partitioning process - particularly if carrying out the activity whilst users are online.
4. Performance and functional testing of the chosen reversion strategy (e.g. restore from backup or online table redefinition).