Tuesday, June 29, 2021
Developing and Deploying Customizations in Oracle E-Business Suite Release 12.2 (Doc ID 1577661.1)
This document describes how to develop and deploy customizations in an Oracle E-Business Suite Release 12.2 environment. Follow these instructions to ensure that your customizations are handled appropriately in conjunction with the Online Patching feature introduced in Release 12.2.
Note: For additional information on customizations to Oracle E-Business Suite, refer to the following documents:
Guidance for Integrating Custom and Third-Party Products With Oracle E-Business Suite Release 12.2, Document 1916149.1
Oracle E-Business Suite Release 12.2 Upgrade Considerations for OAF-based Applications and Oracle CRM Technology Foundation, Document 1927975.1, for customers who have installed or upgraded to Release 12.2.4 or higher
There is a change log at the end of this document.
In This Document
This document is divided into the following sections:
Part 1: Developing and Deploying Customizations in Oracle E-Business Suite Release 12.2
Section 1.1: Working with Editions
Section 1.2: Applying Online Patches
Section 1.3: Developing Customizations
Section 1.4: Developing and Deploying Custom Database Objects
Section 1.5: Deploying Custom Application Tier Objects
Section 1.6: Component-Specific Steps for Application Tier Objects
Section 1.7: Troubleshooting
Part 2: Database Object Development Standards for Online Patching
Section 2.1 Introduction to Database Object Development Standards
Section 2.2 Editioned Objects
Section 2.3 Effectively-Editioned Objects
Section 2.4 Non-Editioned Objects
Section 2.5 Additional Information and Examples
Appendix: Additional Information
Working with Customizations using Downtime Patching
Part 1: Developing and Deploying Customizations in Oracle E-Business Suite Release 12.2
Section 1.1: Working with Editions
Note: This section replaces the section "Working with Editions" in Chapter 6, "Developer Guidelines for Customizations in an Online Patching-Enabled Environment," of the Oracle E-Business Suite Developer's Guide, Part No. E22961, in the Release 12.2.2 documentation library.
An Oracle E-Business Suite Release 12.2 installation now includes two editions (versions) of the application code and seed data. The file system contains two complete copies of the Oracle E-Business Suite and application-tier technology files. In the database, we use the Edition-based Redefinition feature to create a new database edition for each online patching cycle.
The "Run Edition" is the code and data used by the running application. The Run Edition includes a complete application-tier file system along with all objects and data visible in the default edition of the database. As a developer, you will connect to the Run Edition whenever you are engaged in normal development activity on the system.
The "Patch Edition" is an alternate copy of Oracle E-Business Suite code and seed data that is updated by Online Patching. The Patch Edition includes a complete copy of the application-tier file system and editioned database code objects. The Patch Edition is only usable when an Online Patching session is in progress. End users cannot access the Oracle E-Business Suite Patch Edition, but as a developer you may need to connect to the Patch Edition of a system when applying patches or debugging problems with Online Patch execution.
The Oracle E-Business Suite application-tier files are installed in a base directory of the customer's choosing. Within that base directory you will now find three important sub-directories:
fs1 - file system 1 (either run or patch edition)
fs2 - file system 2 (alternate of file system 1)
fs_ne - non-editioned file system, for data files
The fs1 and fs2 directories contain the Run Edition and Patch Edition files for Oracle E-Business Suite. The "run" and "patch" file system designation will switch back and forth between fs1 and fs2 for each patching cycle. The file system designation is automatically maintained by Online Patching in the Applications Context file and the FILE_EDITION environment variable in the environment script for each file system:
$ # Change to EBS base directory (example)
$ cd /u01/R122_EBS
$ # Show file system designations
$ grep FILE_EDITION= */EBSapps/appl/*.env
fs1/EBSapps/appl/gbzd122x_slc04axp.env:FILE_EDITION="patch"
fs2/EBSapps/appl/gbzd122x_slc04axp.env:FILE_EDITION="run"
In the above example, 'fs2' is the Run Edition file system, and 'fs1' is the Patch Edition.
Section 1.1.1: Connecting to the Run Edition
The Run Edition file system and database edition are used by the running application. Normal development activity (writing and testing new code) will also take place in the Run Edition of a development environment.
Oracle E-Business Suite Release 12.2.3 and higher includes a script to set the run or patch edition environment by edition type. The script is called "EBSapps.env" and is found in the base directory of an Oracle E-Business Suite application-tier installation.
$ source /u01/R122_EBS/EBSapps.env run
E-Business Suite Environment Information
----------------------------------------
RUN File System : /u01/R122_EBS/fs2/EBSapps/appl
PATCH File System : /u01/R122_EBS/fs1/EBSapps/appl
Non-Editioned File System : /u01/R122_EBS/fs_ne
DB Host: slc04axp.us.oracle.com Service/SID: gbzd122x
Sourcing the RUN File System ...
$ echo $FILE_EDITION
run
$ sqlplus
SQL> select ad_zd.get_edition_type from dual;
GET_EDITION_TYPE
----------------
RUN
Section 1.1.2: Connecting to the Patch Edition
The Patch Edition contains a copy of the application code that can be modified by Online Patching. A developer may need to connect to the Patch Edition of an Oracle E-Business Suite installation in order to apply patches by hand, or to investigate problems with Online Patch execution.
Warning: It is only safe to connect to the patch edition while an Online Patching session is in progress. Specifically, the Patch Edition is active after the "adop phase=prepare" operation, and persists until the cutover or abort operation is run.
Connect to the patch edition using the EBSapps.env script as follows:
$ source /u01/R122_EBS/EBSapps.env patch
E-Business Suite Environment Information
----------------------------------------
RUN File System : /u01/R122_EBS/fs2/EBSapps/appl
PATCH File System : /u01/R122_EBS/fs1/EBSapps/appl
Non-Editioned File System : /u01/R122_EBS/fs_ne
DB Host: slc04axp.us.oracle.com Service/SID: gbzd122x
Sourcing the PATCH File System ...
$ echo $FILE_EDITION
patch
$ sqlplus
SQL> select ad_zd.get_edition_type from dual;
GET_EDITION_TYPE
----------------
PATCH
The application-tier Patch Edition environment is configured to connect to the database patch edition by default. If a database patch edition is not active, then attempting to connect to the database from the application-tier patch edition environment will fail.
Note: When you connect to the patch edition using the command
$ source /EBSapps.env patch
it sets the TWO_TASK, APPS_JDBC_URL, and AD_APPS_JDBC_URL environment variables (among many others), which define the database connection to use. When running a command line tool (especially Java programs), you must figure out which of the available environment variables values can be used to construct a command line for the tool. For example, in the case of XDOLoader, you should use AD_APPS_JDBC_URL, as in:
$ java oracle.apps.xdo.oa.util.XDOLoader DOWNLOAD \
-DB_USERNAME apps -DB_PASSWORD apps -JDBC_CONNECTION "$AD_APPS_JDBC_URL"
Section 1.1.3: Displaying Edition Status
To help keep track of what environment and edition you are connected to, it can be helpful to set the TWO_TASK or FILE_EDITION environment variable as your shell prompt.
$ PS1='$TWO_TASK> '
zd122_patch>
You can find out whether a system is in an Online Patching cycle using the "adop -status" command.
$ adop -status
Enter the APPS password:
Current Patching Session ID: 60
Node Name Node Type Phase Status Started Finished Elapsed
----------- ---------- ---------- -------- ------------------------- ------------------------- ------------
slc04axp master PREPARE COMPLETED 02-JUL-13 04:03:25 -07:00 02-JUL-13 05:03:32 -07:00 1:00:07
APPLY COMPLETED 09-JUL-13 12:20:45 -07:00 09-JUL-13 01:23:00 -07:00 1:02:15
CUTOVER COMPLETED 10-JUL-13 09:11:41 -07:00 10-JUL-13 09:18:47 -07:00 0:07:06
CLEANUP COMPLETED 10-JUL-13 09:29:53 -07:00 10-JUL-13 09:52:50 -07:00 0:22:57
If the PREPARE status is COMPLETED and the CUTOVER status is not COMPLETED, then an online patching session is in progress and it is valid to connect to the patch edition of the environment.
You can also see the names of past and present database editions using the ADZDSHOWED.sql script.
$ sqlplus @ADZDSHOWED
"---- Editions ----"
Edition Name Type Status Current?
--------------- -------- -------- --------
ORA$BASE RETIRED
V_20120510_1507 OLD RETIRED
V_20120510_1547 RUN ACTIVE CURRENT
V_20120511_1528 PATCH ACTIVE
The script lists the existing database editions and identifies the OLD, RUN, and PATCH editions. The Current flag indicates which edition you are currently in.
From SQL*Plus it is possible to change your current edition.
SQL> exec ad_zd.set_edition('PATCH')
Section 1.1.4: Tools and Scripts for Edition-based Development
The examples in this guide use various SQL*Plus scripts and command line tools like adop, xdfgen.pl and xdfcmp.pl. The scripts and tools used in Online Patching are often dependent on a specific code level in the rest of the system, so when using an Oracle E-Business Suite environment for development make sure to use the scripts and tools that come with that environment. Connect to the application-tier host for your development environment and source the Run Edition environment file.
$ source /u01/R122_EBS/EBSapps.env run
...
$ which adop
/u01/R122_EBS/fs_ne/EBSapps/appl/ad/bin/adop
$ which xdfgen.pl
/u01/R122_EBS/fs2/EBSapps/appl/fnd/12.0.0/bin/xdfgen.pl
$ which xdfcmp.pl
/u01/R122_EBS/fs2/EBSapps/appl/fnd/12.0.0/bin/xdfcmp.pl
There are a number of SQL*Plus scripts that can provide useful information about the state of your editioned development environment. All ADZD* scripts are found under $AD_TOP/sql. For convenience, you can add this directory to the SQLPATH environment variable so that you can refer to the scripts by simple name.
$ SQLPATH=$AD_TOP/sql; export SQLPATH
ADZDDBCC - database compliance checker, shows violations of the database object development standards described later in this document. Warning: this script takes a long time to run.
ADZDSHOWED - Show database editions and current edition.
ADZDSHOWLOG - Show full diagnostic log for online patching infrastructure.
ADZDSHOWLOGEVT - Show only event and error messages from online patching diagnostic log (a useful summary, without the detailed statement text).
ADZDSHOWLOGERR - Show only error messages from online patching diagnostic log.
ADZDSHOWEV TABLE_SYNONYM_NAME - Show editioning view column mapping for table.
ADZDSHOWTAB TABLE_SYNONYM_NAME - Show table information and related objects.
ADZDSHOWMV MVIEW_NAME - Show materialized view information and related objects.
ADZDSHOWTS - Show important tablespace status. Ensure that you have enough SYSTEM tablespace.
ADZDCMPED - Compare Patch Edition with Run Edition. Warning: this script may take a long time to run.
ADZDSHOWDDLS - Show stored DDL summary by phase.
ADZDALLDDLS - Show stored DDL statement text.
ADZDDDLERROR - Show stored DDL execution errors and messages.
adutlrcmp - Recompile all objects, with before/after status report. Warning: this script may take a long time to run.
The following scripts are for experts:
ADZDSHOWOBJS - Show Object Summary per edition. Counts of actual and stub (inherited) editioned object per edition.
ADZDSHOWAOBJS - Show Actual Objects in the current edition. These are the editioned objects that have been changed by the patch.
ADZDSHOWIOBJS - Show Inherited Objects in the current edition. These are the editioned objects that remain untouched in the patch edition. This script is used to confirm that the adop actualize_all command has worked properly.
ADZDSHOWCOBJS - Show Covered Object Summary per edition. Count of objects in old editions that have a replacement in the run edition. This script is used to confirm that the adop cleanup command has worked properly.
ADZDSHOWCOBJX - Show Covered Object List. List of objects in old editions that have a replacement in the run edition.
ADZDSHOWSM - Show Seed Manager status.
ADZDSHOWTM - Show Table Manager status.
ADZDSHOWAD - AD (online patching) database object status
ADZDSHOWSES - Show sessions connected to the database (by edition).
ADZDSHOWDEP OBJECT_NAME - Show objects that OBJECT_NAME depends on.
ADZDSHOWDEPTREE OBJECT_NAME - Show full dependency tree of objects that OBJECT_NAME depends on.
Section 1.2: Applying Online Patches
Note: This section should follow the section "Working with Editions" in Chapter 6, "Developer Guidelines for Customizations in an Online Patching-Enabled Environment," of the Oracle E-Business Suite Developer's Guide, Part No. E22961.
Before developing on an editioned application system, you should understand how online patches are applied to that system. Application development is done on the Run Edition of a development system, while an online patch is always applied to the Patch Edition of a target system. The online patch may take the form of a Manual Patch or an ARU patch (Oracle patch).
A manual patch consists of a set of files plus a set of installation actions that are executed to apply the changes to a target system. The procedure for applying a manual patch to an editioned system is similar to that of earlier non-editioned releases, with two important differences:
Manual patching actions must be executed in the Patch Edition of the target system.
Manual patching actions that affect the file system must be repeated or copied to the alternate file system on the next patching cycle.
An ARU Patch consists of a set of files that may be annotated with "dbdrv" comments, which are processed by ARU to produce a patch bundle. The patch bundle can then be applied automatically using the "adop phase=apply" command. This is the equivalent of running "adpatch" on non-editioned system. The "adop phase=apply" command executes all patch actions required to apply the update to the patch edition of the target system, and automatically handles file system synchronization on the next patching cycle.
Section 1.2.1: The Online Patching Cycle
Patches to an editioned system are normally applied within the context of an Online Patching Cycle. The online patching cycle has several phases which proceed in order.
Prepare - creates the patch edition.
Apply - apply ARU or manual patches to the patch edition.
Finalize - perform any actions required to prepare for cutover.
Cutover - Promote Patch Edition to be the new Run Edition.
Cleanup - remove obsolete code and data from old editions.
Online Patching Cycle phases are executed using the new "adop" command line tool. Syntax for each of the phases is described below. At any time you can get adop command line help by running "adop -help". You can check the status of the patching cycle by running "adop -status".
The following sections describe how to progress through each phase. For more information on the Online Patching Cycle, refer to the Oracle E-Business Suite Maintenance Guide, Part No. E22954.
Section 1.2.2: Prepare
Before applying a patch, you must start an Online Patching Cycle. This is done using the adop "prepare" command. Connect to the primary application-tier node of your target system and source the run edition environment. Then execute the prepare command.
$ source /u01/R122_EBS/EBSapps.env run
...
$ adop phase=prepare
The adop utility may first execute the cleanup phase from the previous cycle if needed, and will then proceed to prepare the patch edition for a new Online Patching Cycle. To prepare the patch edition, adop will:
Validate that the system is ready to start a new patching cycle.
Create a new database patch edition
Synchronize the file system patch edition with the run edition
Configure the patch edition for use by the patching tools
File system synchronization may be done by applying the delta (changes) from the previous patching cycle, or by re-creating the entire patch edition file system as a fresh copy of the run edition (called "fs_clone"). When complete, check the exiting status code (success is '0'):
adop exiting with status = 0 (Success)
If there were any problems with the prepare phase, check Section 1.7: Troubleshooting and resolve the problem. Then run the prepare command again.
After a successful prepare phase, the database and file system patch edition will contain a copy of the run edition code and seed data. You can now apply ARU patches and manual patches to the patch edition.
Section 1.2.3: Apply
Once the Patch Edition is prepared, you can apply any number of ARU patches or manual patches to the patch edition. Changes to the patch edition are isolated from the run edition, which is still available for use.
Apply an ARU Patch
Before applying an ARU patch, you must first download the patch bundle from ARU through the web user interface (support.oracle.com). The downloads will be in the form of ZIP files. Place the ZIP files in the "$PATCH_TOP" directory on the application-tier installation of your target application system, and then unzip all ZIP files.
ARU patches are applied to the patch edition using the "adop phase=apply" command. The command accepts a "patches=..." parameter where you can specify a single patch or a comma-separated list of patches.
$ adop phase=apply patches=16605855
...
$ adop phase=apply patches=15111111,15222222
...
Note that the adop command will apply patches to the patch edition no matter what edition your current environment is set to.
If the adop apply commands fail, check Section 1.7: Troubleshooting and correct the problem, then run the adop apply command again, adding the "restart=yes" option.
$ adop phase=apply patches=16605855 restart=yes
...
In some cases, an error when applying a patch can be corrected by applying a replacement patch. You can abandon an existing failed patch and apply the replacement patch by running the apply command with the "abandon=yes" parameter.
$ adop phase=apply patches=16699999 abandon=yes
...
Apply a Manual Patch
Manual patches must be applied to the patch edition of a target system "by hand". Do this by changing to the patch edition environment and manually executing the patching actions necessary to install the update. The manual patch actions are identical to those you would take when applying manual patches to a non-editioned system; the only difference is that on an editioned system, these actions take place in the patch edition.
Manual patching actions normally involve the following steps:
Copy patch files to their destination directories in the patch edition.
Execute any commands necessary to deploy changes to the file system.
Execute any commands necessary to deploy changes to the database.
Execute any commands necessary to generate or compile dependend files or objects.
Update the custom synchronization driver to include any file system actions that must be executed again on the next prepare phase, in order to synchronize the alternate file system. See Section 1.5.4: Adding Entries to the Custom Synchronization Driver File.
The exact commands needed to apply a manual patch vary by the type of files or database objects being patched. These required deployment commands for each file and object type are discussed later in this document.
The following is a simple example of installing a new server PL/SQL package.
$ source /u01/R122_EBS/EBSapps.env patch
...
$ cd $PATCH_TOP/manual_000
$ apply_fs.sh
# apply patch to file system
cp fnd/patch/115/sql/* $FND_TOP/patch/115/sql
$ apply_db.sh
# apply patch to database
sqlplus apps/apps @$FND_TOP/patch/115/sql/XYZUTILS.pls
sqlplus apps/apps @$FND_TOP/patch/115/sql/XYZUTILB.pls
After applying an ARU patch or a manual patch you can look at the patch edition file system or database status to verify that the patching actions were successful and that the resulting patch edition code and seed data are as expected. When you have sourced the patch edition environment, the default database connection goes to the patch edition. Although you cannot run the application user interface or program code in the patch edition, it is possible to connect to the database via SQL*Plus or other tools and confirm that the desired changes have been successfully implemented. To confirm the updates of the previous manual patching example, you could do the following:
$ source /u01/R122_EBS/EBSapps.env patch
...
$ sqlplus
Enter password: password
SQL> show errors package XYZ_UTIL
SQL> show errors package body XYZ_UTIL
SQL> quit
Once all patching actions are complete and validated, you may proceed to the finalize phase.
Section 1.2.4: Finalize
The finalize phase is used by the Online Patching tool to perform any final actions needed to make the system ready for the fastest possible cutover. The finalize command is run as follows:
$ adop phase=finalize
If the finalize command returns an error, the system is not ready for cutover. In this case, check Section 1.7: Troubleshooting, correct the problem and run the finalize command again.
After successful completion of the finalize phase, the system is ready for cutover, but you do not need to execute the cutover right away; you can delay executing cutover until a convenient or predetermined time in the future. You may also apply additional patches if needed, but you will need to run the finalize phase again after doing so.
Section 1.2.5: Cutover
The cutover phase will configure the patch edition to become the new run edition, and restart the application on this new run edition.
$ adop phase=cutover
...
$ source /u01/R122_EBS/EBSapps.env run
After successful completion of the cutover phase, the application will be up and running on the new edition, ready for use. Since the run/patch designation of the dual file systems are swapped during cutover, you must re-source the run edition environment directly after cutover.
Important: Remember to re-source the run edition environment directly after cutover.
Section 1.2.6: Cleanup
The cleanup phase will remove unnecessary code and data from old editions that are no longer needed by the application. Cleanup should be run after cutover, at any time before the next prepare phase. It is best to run cleanup immediately after cutover so that there is no delay when preparing the next online patching cycle. There are three levels of cleanup available:
quick - the minimal cleanup required before starting the next patching cycle.
standard - (default) removes obsolete code and seed data from old editions.
full - removes all obsolete code, data, and table columns.
Standard cleanup is the default, and is recommended to avoid a buildup of obsolete code objects in old editions.
$ adop phase=cleanup
Use quick cleanup when you need to start the next patching cycle as soon as possible.
$ adop phase=cleanup cleanup_mode=quick
Use full cleanup to remove obsolete table columns. Full cleanup is required after aborting an online patching cycle.
$ adop phase=cleanup cleanup_mode=full
Section 1.2.7: Special Patching Actions
For completeness, the following actions are also listed here. Refer to the Oracle E-Business Suite Maintenance Guide, Part No. E22954 for more information on these commands.
FS Clone
The "fs_clone" command recreates the patch edition file system by making a full copy of the run edition file system. This command is required when the patch edition file system cannot be automatically synchronized with the run edition file system by adop. Run the fs_clone command if you have done any of the following actions:
Applied middle-tier technology patches to the run edition
Changed run edition files manually (outside of online patching)
Aborted an online patching cycle
The fs_clone command is executed as follows:
$ adop phase=fs_clone
Abort
If an online patching cycle has failed for some reason that cannot be corrected, you can abort the online patching cycle and return to normal operation. The adop "abort" command drops the database patch edition and removes or abandons any changes made during the the online patching cycle. If the online patching cycle has completed the cutover phase, then you can no longer abort the patching cycle. '
When aborting an online patching cycle, you must also run the cleanup and fs_clone commands to fully eliminate changes from the patching cycle. The abort command is run as follows:
$ adop phase=abort
$ adop phase=cleanup
$ adop phase=fs_clone
Section 1.3: Developing Customizations
For Oracle E-Business Suite developers, development activity can be considered in two parts:
Application Development: Creating or revising part of an application definition, functional testing, source control of updates.
Patch Development: Creating a patch to deliver and install the changed application definition on a target system, patch testing.
Application Development is done in the Run Edition of an Oracle E-Business Suite development environment. The runtime application user interface and other services can only operate against the run edition of a system. During application development, the developer is directly modifying the definition of the running application in a development database. Once satisfied with the updated application definition, the developer proceeds to patch development.
Patch Development involves collecting or extracting the files that contain the application definition to be patched, along with any other logic necessary to deliver, build and deploy these changes to the target system. Customers may create manual patches.
To create a manual patch, the developer creates a patch directory containing the application definition files to be delivered, along with an "apply" script. The apply script contains the commands to deliver, build, and deploy the application definition to the target system. Patch apply scripts can be initially tested in the run edition of a development database, but final testing must take place in the patch edition of a test system during an online patching cycle.
The rest of this section describes how to create and patch the various types of application definition changes in an editioned application environment.
Application-Tier Files
Application-tier files (also known as middle-tier files) are those files that are only used by middle-tier application services such as the OA Framework, Forms, Reports, Concurrent Programs, JSP files, and so on. An application developer working on a development system can create or modify middle-tier files directly in the run edition file system. Changes to some file types require a build or deployment action to be executed before the change will take effect. Any required build or deployment actions will be explained in the specific instructions for each file type below, but the general development approach for middle-tier file changes is as follows:
Connect to the run edition of your development environment.
Check out the desired source files from the source control system.
Edit source files to implement desired update.
Build/deploy changes into the run edition of the development environment and test.
When development is complete, check in the changes and make note of new files and versions.
Create a patch for the changed files. For manual patches, create a script that copies changed files to the target system and then executes any build or deploy actions that are required.
Section 1.3.1: Setting Up an Environment for Customizations
If you are developing customizations for the first time, begin by setting up your custom application on your development environment. See: Overview of Setting Up Your Application Framework, Oracle E-Business Suite Developer's Guide.
As part of setting up your application, use the AD Splicer utility (adsplice) to register your custom application as a product within Oracle E-Business Suite. For instructions on running adsplice, see: Applications DBA System Configuration Tools, Oracle E-Business Suite Setup Guide, and Applications DBA System Maintenance Tasks and Tools, Oracle E-Business Suite Maintenance Guide.
Note: In Release 12.2, you should use adsplice to register your application in order to ensure that the application is set up for online patching. Do not use the Applications window to register applications in this release.
Note: When installing or upgrading to Release 12.2, do not run adsplice until you have applied the 12.2.2 Release Update Pack. Running adsplice before your instance is at the 12.2.2 code level may cause file synchronization issues.
You can use Patch 3636980, "Support Diagnostics (IZU) patch for AD Splice", to help you create your custom application. See: Creating a Custom Application in Oracle E-Business Suite Release 12.2, Document 1577707.1.
On your development environment, you should invoke adsplice from the run file system. Connect to the run file system as described in Section 1.1.1: Connecting to the Run Edition. Then run the adsplice command.
In Oracle E-Business Suite Release 12.2, adsplice performs the following steps:
Makes the new user edition-enabled.
Enables Edition-Based Redefinition (EBR) for the custom objects.
When you start the next online patching cycle, the prepare phase will run fs_clone to synchronize the two file systems.
Note: If you upgraded your environment from an earlier release to Release 12.2, then you should run adsplice for your custom application again after the upgrade, using the same application ID and application name as when you originally added your custom application. Running the Release 12.2 version of adsplice after the upgrade helps ensure that the custom top folder for your application will be included when the two file systems are synchronized during online patching.
If your customizations will include custom Java or BC4J code or extensions, apply the following patches to your development environment in hotpatch mode using the AD Online Patching utility (adop). For instructions on running adop, see: The adop Utility, Oracle E-Business Suite Maintenance Guide.
17217965:R12.TXK.C (TEMPLATE CHANGE REQUIRED TO UPLOAD THE CLASS FILES RELATED TO CUSTOMIZATIONS)
17217772:R12.AD.C (NEED UTILITY TO GENERATE CUSTOMALL.JAR)
Section 1.3.2: Building Customizations
After setting up your development environment, build your customizations according to the developer's guide for the product or component you are customizing, as well as any guidelines in Section 1.6: Component-Specific Steps for Application Tier Objects.
For customizations developed directly in the Oracle E-Business Suite instance, you should download the custom object files that you will deploy to your production environment.
Connect to the run edition file system on your development environment.
Use the appropriate utility for your product or component to download the custom object files.
For customizations developed in a tool outside the Oracle E-Business Suite instance, you should save the custom object files from that tool. To deploy the custom object files in your development environment for testing, perform the following steps:
Connect to the run edition file system on your development environment.
Copy the custom files to the appropriate directory on the run edition file system.
If you copied any custom files under the $JAVA_TOP directory, run the adcgnjar utility to generate and sign a JAR file containing these files. When prompted, enter the user name and password of the APPS user. See Section 1.5.3: Running the adcgnjar Utility.
If necessary, use the appropriate utility for your product or component to upload the custom files to the database.
Add entries for the custom files to the custom synchronization driver file to ensure that the adop utility synchronizes these files between the run file system and the patch file system the next time you run the prepare phase. See Section 1.5.4: Adding Entries to the Custom Synchronization Driver File.
Section 1.4: Developing and Deploying Custom Code and Custom Database Objects
For more information on database object development standards, see: Part 2: Database Object Development Standards for Online Patching.
Section 1.4.1: Recommended Approaches for Deploying Custom Code
When patching custom code into an Oracle E-Business Suite installation, there are two recommended approaches.
Apply customizations as an online patch: The custom code is patched into the patch edition when an online patching cycle is open. The patch must follow Online Patching Development Standards. In this case, the custom patch acts like any other Oracle E-Business Suite online patch and receives the same benefits (no additional downtime, ability to review patching results before cutover, ability to abort the patch if there is trouble). This is the most recommended approach but requires compliance to the full set development standards.
Apply customizations as a downtime patch: The custom code is patched into the run edition, either during an extended online patching cutover downtime, or as a separate downtime event. In this case, the custom patch need only comply with only a minimal set of development standards, and in particular, the patch is free to use traditional table upgrade scripts as the method for data upgrade. Downtime patching of customizations is recommended if the customer is not sensitive to downtime and does not want to ensure that their custom development meets full online patching development standards.
An approach that explicitly discouraged is hot patching of customizations. Applying custom changes to the run edition of the system while the system is online carries the risk of causing large chain-reaction invalidation of objects in the dependency tree of whatever is getting patched. This can cause runtime failure in user sessions, and the code may temporarily be in an inconsistent state which can lead to data corruption, runtime exceptions, or other unexpected behavior while the patch is being applied.
Note: As a customer, you do not need to commit to only the online approach or only the downtime approach; that is, you can make this decision on a case-by-case basis. Online patching of code-only changes requires no extra effort from the developer compared to downtime patching, because the process of actually applying code changes is identical (once you have set your environment to the correct edition). So you can do simpler patches online and reserve downtime patching for situations where the patch will modify tables or other non-editioned objects in a way that is not compliant with online patching.
Section 1.4.2: Editioned Database Objects
Note: This section replaces the section "Editioned Database Objects" in Chapter 6, "Developer Guidelines for Customizations in an Online Patching-Enabled Environment", of the Oracle E-Business Suite Developer's Guide, Part No. E22961, in the Release 12.2.2 documentation library.
Editioned Database Objects may have a different definition in each database edition. This means that such objects can be created or replaced in the patch edition without affecting the running application. Editioned database object types are:
View (Ordinary)
PL/SQL Package
PL/SQL Trigger
User-Defined Type (Editioned)
Synonym
Virtual Private Database Policy
For more information on these objects, refer to the Oracle Database Administrator's Guide.
Step 1: Create or Replace Editioned Database Objects in your development database:
An application developer can create or replace editioned database objects in the run edition of a development database using whatever scripts or tools they normally use. Typically this involves editing SQL scripts that contain DDL statements, and then applying the scripts to the development database. For example:
sqlplus @XYZUTILS.pls"
sqlplus @XYZUTILB.pls"
sqlplus
exec ad_zd.compile
quit
If your application changes will cause significant object invalidation in the development database, you may wish to call the "ad_zd.compile" procedure to recompile invalid objects in the run edition.
Note: Developers often use the user_objects or all_objects data dictionary view to confirm that there are no unexpected invalid objects. Due to a database limitation these dictionary views only return correct object status after running a full compilation procedure (utl_recomp.recomp_parallel or ad_zd.compile). As a workaround, you can check object status using the ad_objects view included with online patching.
select * from ad_objects where status='INVALID';
After deploying changes, confirm that there are no unexpected invalid objects and then test your changes in the running application. When satisfied, make note of the changed DDL scripts and proceed to the next step.
Step 2: Create the patch
Patch files in the above example would be:
fnd/patch/115/sql/XYZUTILS.pls
fnd/patch/115/sql/XYZUTILB.pls
The manual apply actions for the file system would be:
cp fnd/patch/115/sql/* $FND_TOP/patch/115/sql
The manual apply actions for the database would be:
sqlplus @$FND_TOP/patch/115/sql/XYZUTILS.pls
sqlplus @$FND_TOP/patch/115/sql/XYZUTILB.pls
Section 1.4.3: Effectively-Editioned Database Objects
Note: This section replaces the sections "Tables" and "Materialized Views" in Chapter 6, "Developer Guidelines for Customizations in an Online Patching-Enabled Environment", of the Oracle E-Business Suite Developer's Guide, Part No. E22961, in the Release 12.2.2 documentation library.
Section 1.4.3.1: Tables
Since the application is still running during an online patch (and the application data is continuously changing), it is not possible to upgrade application data using a one-time update script. Instead we will need to use a new technique involving Editioning Views and Crossedition Triggers, described below.
Note: This section describes how to develop and patch ordinary application data tables. But there are some special types of tables that have additional or alternate standards and procedures. If you are working with one of these special table types, please consult that section of the guide instead.
Create a New Table
This example will show how to develop and patch a new table on an editioned development environment. Suppose we want to create a table that holds "service information" per user account for some application with the following logical table structure:
XYZ_USER_SERVICE
Name Null? Type
----------------------------------------- -------- --------------
USER_ID NOT NULL NUMBER
-- PK, FK to FND_USER.USER_ID
SERVICE_TYPE NOT NULL VARCHAR2(8)
-- 'BASIC' - normal service
-- 'PREMIUM' - premium service
COMMENTS VARCHAR2(1000)
Create the initial table definition in your development database.
In this example we use SQL*Plus to execute the required DDL. This step includes creation of any required indexes, storage properties, and so on. As with all development, you should be connected to the Run Edition of your EBS development environment.
create table APPLSYS.XYZ_USER_SERVICE
(
USER_ID NUMBER(15) not null,
SERVICE_TYPE VARCHAR2(8) not null,
COMMENTS VARCHAR2(1000)
)
tablespace APPS_TS_TX_DATA
/
create unique index APPLSYS.XYZ_USER_SERVICE_U1
on APPLSYS.XYZ_USER_SERVICE ( USER_ID )
tablespace APPS_TS_TX_IDX
/
Please avoid using official database constraints for Primary Key and Unique Key enforcement. Unique indexes achieve the goal and are easier to manage under Online Patching.
Upgrade the table for Online Patching using the AD_ZD_TABLE.UPGRADE procedure.
This will generate an Editioning View (EV) for the table and then create an APPS synonym that points to the Editioning View.
exec ad_zd_table.upgrade('APPLSYS', 'XYZ_USER_SERVICE')
The table is now ready for use from the APPS schema. The generated EV is named XYZ_USER_SERVICE# and looks exactly like the table at this point. When the table structure is patched in the future, the EV will serve to map logical column names (used by the application code) to the table columns that store the data in each edition. You can see a display of the EV column mapping with the ADZDSHOWEV.sql script:
$AD_TOP/sql/ADZDSHOWEV.sql XYZ_USER_SERVICE
-- EV Column Mapping
VIEW_COLUMN -> TABLE_COLUMN
------------------------------ ---- -------------------
USER_ID = USER_ID
SERVICE_TYPE = SERVICE_TYPE
COMMENTS = COMMENTS
Now we can add some data to the table for demonstration purposes:
insert into xyz_user_service (user_id, service_type, comments)
values (0, 'PREMIUM', 'Big Spender');
insert into xyz_user_service (user_id, service_type, comments)
values (2, 'BASIC', 'Mr Prudent');
commit;
Extract the table definition from your development database using the xdfgen.pl utility.
Due to a database requirement you must first insert at least one row into the table before extraction will work.
For all instances on R12.AD.C.Delta.8 and higher, use the following command. Enter the password when prompted. Alternatively, you could pass the password on the command line but this method might be insecure:
perl xdfgen.pl XYZ_USER_SERVICE
For all instances on R12.AD.C.Delta.7:
perl xdfgen.pl / XYZ_USER_SERVICE
For single node database instances on R12.AD.C.Delta.6 and lower:
perl xdfgen.pl /@ XYZ_USER_SERVICE
For RAC instances on R12.AD.C.Delta.6 and lower:
perl xdfgen.pl /@ XYZ_USER_SERVICE
This produces a file called 'xyz_user_service.xdf' that contains the definition of the table along with any related indexes, sequences, and policies.
Create the patch.
Patch Files:
fnd/patch/115/xdf/xyz_user_service.xdf version 1
Note that version 1 of the file xyz_user_service.xdf contains the initial table definition. In the example in the next section, you create a new patch that introduces a change to the table definition which is shipped in the version 2 of the file xyz_user_service.xdf. In subsequent sections you create new patches that introduce changes that are shipped in later versions of the file (version 3, version 4, and so on).
Manual apply phase actions for the file system:
cp fnd/patch/115/xdf/* $FND_TOP/patch/115/xdf
Manual apply phase actions for the database:
For instances on R12.AD.C.Delta.8 and higher, use the following command. Enter the password when prompted. Alternatively, you could pass the password on the command line but this method might be insecure:
xdfcmp.pl $FND_TOP/patch/115/xdf/xyz_user_service.xdf apps
For instances on R12.AD.C.Delta.7 and lower:
xdfcmp.pl /@$TWO_TASK $FND_TOP/patch/115/xdf/xyz_user_service.xdf /
When the patch is applied, XDF will create the table and index, and will automatically call the AD_ZD_TABLE.UPGRADE procedure to generate the editioning view and APPS table synonym.
Add a new column to a table
This step demonstrates adding a new logical column to a table (as opposed to revising an existing logical column, which we will cover in a later section). To demonstrate this procedure, will add a new flag to our example service table that indicates whether the service is enabled. The desired logical table structure is as follows:
XYZ_USER_SERVICE
Name Null? Type
----------------------------------------- -------- --------------
USER_ID NOT NULL NUMBER
-- PK, FK to FND_USER.USER_ID
SERVICE_TYPE NOT NULL VARCHAR2(8)
-- 'BASIC' - normal service
-- 'PREMIUM' - premium service
COMMENTS VARCHAR2(1000)
==> SERVICE_STATUS NOT NULL VARCHAR2(8)
==> -- 'ENABLED' - service is active
==> -- 'DISABLED' - service is not active.
Create the new column in your development database.
We can do this in SQL*Plus as follows:
alter table APPLSYS.XYZ_USER_SERVICE
add (SERVICE_STATUS varchar2(8) default 'ENABLED' not null)
/
Note: When adding a NOT NULL column, it is recommended to choose a default value. Even if the column value will be populated through application logic you should still specify a default value for a NOT NULL column. The default value will allow XDF/ODF to create the column with the NOT NULL constraint in a single pass. Populating a new or revised column during online patching is done using a crossedition trigger which will be explained later.
Regenerate the editioning view using AD_ZD_TABLE.PATCH. Whenever you directly alter the structure of a table, you must call the AD_ZD_TABLE.PATCH procedure. The PATCH procedure looks at the physical table columns and then generates the editioning view which presents the logical columns for that table. The PATCH procedure is called automatically when applying table structure changes using XDF or ODF.
exec ad_zd_table.patch('APPLSYS', 'XYZ_USER_SERVICE')
@ADZDSHOWEV XYZ_USER_SERVICE
-- EV Column Mapping
VIEW_COLUMN -> TABLE_COLUMN
------------------------------ ---- ------------------------------
USER_ID = USER_ID
SERVICE_TYPE = SERVICE_TYPE
COMMENTS = COMMENTS
SERVICE_STATUS = SERVICE_STATUS
The new column is now present in the Editioning View.
Extract the updated table definition from your development database.
For instances on R12.AD.C.Delta.8 and higher, use the following command. Enter the password when prompted. Alternatively, you could pass the password on the command line but this method might be insecure:
perl xdfgen.pl XYZ_USER_SERVICE
For all instances on R12.AD.C.Delta.7:
perl xdfgen.pl / XYZ_USER_SERVICE
For single node database instances on R12.AD.C.Delta.6 and lower:
perl xdfgen.pl /@ XYZ_USER_SERVICE
For RAC instances on R12.AD.C.Delta.6 and lower::
perl xdfgen.pl /@ XYZ_USER_SERVICE
Create the patch.
Patch Files:
fnd/patch/115/xdf/xyz_user_service.xdf version 2
Manual apply phase actions for the file system:
cp fnd/patch/115/xdf/* $FND_TOP/patch/115/xdf
Manual apply phase actions for the database:
For instances on R12.AD.C.Delta.8 and higher, use the following command. Enter the password when prompted. Alternatively, you could pass the password on the command line but this method might be insecure:
xdfcmp.pl $FND_TOP/patch/115/xdf/xyz_user_service.xdf
For instances on R12.AD.C.Delta.7 and lower:
xdfcmp.pl / $FND_TOP/patch/115/xdf/xyz_user_service.xdf
Test the patch.
When the patch is applied, XDF will add the new column and automatically call the AD_ZD_TABLE.PATCH procedure on the target system.
Add a new index
This section demonstrates how to add a new index to an existing table. In the following example, we add a non-unique index on the SERVICE_TYPE attribute of our example table. The logical table structure is unchanged.
Create the new index in your development database.
create index APPLSYS.XYZ_USER_SERVICE_N1 on APPLSYS.XYZ_USER_SERVICE
( SERVICE_TYPE )
tablespace APPS_TS_TX_IDX
/
When adding an index it is not necessary to call the AD_ZD_TABLE.PATCH procedure, as the table structure has not changed.
Extract the updated table definition from your development database.
For all instances on R12.AD.C.Delta.8 and higher, use the following command. Enter the password when prompted. Alternatively, you could pass the password on the command line but this method might be insecure:
perl xdfgen.pl XYZ_USER_SERVICE
For all instances on R12.AD.C.Delta.7:
perl xdfgen.pl / XYZ_USER_SERVICE
For single node database instances on R12.AD.C.Delta.6 and lower:
perl xdfgen.pl /@ XYZ_USER_SERVICE
For RAC instances on R12.AD.C.Delta.6 and lower:
perl xdfgen.pl /@ XYZ_USER_SERVICE
When extracting a table definition, XDF also extracts any related index definitions.
Create the patch.
Patch Files:
fnd/patch/115/xdf/xyz_user_service.xdf version 3
Manual apply phase actions for the file system:
cp fnd/patch/115/xdf/* $FND_TOP/patch/115/xdf
Manual apply actions for the database:
For instances on R12.AD.C.Delta.8 and higher, use the following command. Enter the password when prompted. Alternatively, you could pass the password on the command line but this method might be insecure:
xdfcmp.pl $FND_TOP/patch/115/xdf/xyz_user_service.xdf apps
For instances on R12.AD.C.Delta.7 and lower:
xdfcmp.pl /@$TWO_TASK $FND_TOP/patch/115/xdf/xyz_user_service.xdf
Test the patch.
When XDF applies the table definition, it will detect that the target database is missing the new index, and it will create the new index. Note that when the XDF is applied in the Patch Edition of a target system, the new index is initially created with an alternate name, which will then be updated to the correct index name during cutover.
Update an existing column
This section shows how to update an existing logical column. You might need to update an existing logical column either to
Change the column definition (data type, data length, not null constraint)
Change the column data (how data is stored in the column)
To update existing data without disturbing the running application we must create a new physical column (called a revised column) to hold the updated data. Note that online patching tools will not allow you to alter the existing physical column definition in any way, even if the change seems "compatible" with the existing column data. To make any kind of change to an existing column you must code a revised column using the procedure described in this section.
In this example, we upgrade SERVICE_TYPE codes from the original two-value scheme (‘BASIC’, ‘PREMIUM’) to a three-value scheme (‘BRONZE’, ’SILVER’, ’GOLD’). Since the new values are not compatible with the existing application, we must use a revised physical column to hold the new data. The logical name of the column (as exposed through the editioning view) remains the same. The desired logical table structure is as follows:
XYZ_USER_SERVICE
Name Null? Type
----------------------------------------- -------- --------------
USER_ID NOT NULL NUMBER
-- PK, FK to FND_USER.USER_ID
SERVICE_TYPE NOT NULL VARCHAR2(8)
==> -- 'BRONZE' - cheap service (was 'BASIC')
==> -- 'SILVER' - new mid-level service
==> -- 'GOLD' - best service (was 'PREMIUM')
COMMENTS VARCHAR2(1000)
SERVICE_STATUS NOT NULL VARCHAR2(8)
-- 'ENABLED' - service is active
-- 'DISABLED' - service is not active.
Create a revised column in your development database.
Revised columns use a naming standard of COLUMN_NAME#REVISION, where a later REVISION tag must be alphabetically greater than the earlier revision. Since this is the first revision of the column, start with revision ‘1’. The data upgrade logic will be placed in a Forward Crossedition Trigger described later. Alter the table in your development database to add the new revised column, and remember to call the AD_ZD_TABLE.PATCH procedure whenever you change the table structure manually:
alter table APPLSYS.XYZ_USER_SERVICE
add (SERVICE_TYPE#1 varchar2(8) default '*NULL*' not null)
/
exec ad_zd_table.patch('APPLSYS', 'XYZ_USER_SERVICE')
Since the revised column is not null, specify a default value so that the column can be created with the not null constraint in a single operation. The actual value of the column will be populated by a crossedition trigger, so the default value does not matter, but it is useful to specify a default value which clearly indicates that the column is not yet populated.
@ADZDSHOWEV XYZ_USER_SERVICE
-- EV Column Mapping
VIEW_COLUMN -> TABLE_COLUMN
------------------------------ ---- ------------------------------
USER_ID = USER_ID
SERVICE_TYPE ===> SERVICE_TYPE#1
COMMENTS = COMMENTS
SERVICE_STATUS = SERVICE_STATUS
Notice that after executing the PATCH procedure the SERVICE_TYPE column in the EV (the logical column) is now mapped to the revised physical column. Also notice that this new column is not yet populated with data. That comes next.
Create a Forward Crossedition Trigger to populate the revised column.
A Forward Crossedition Trigger (FCET) is a table trigger with a special rule about how it fires: During online patching, the FCET is created in the Patch Edition, but (being a crossedition trigger) it will only fire on changes made in the parent (Run) edition. The upgrade logic is implemented as a trigger instead of a simple update statement so that the upgrade logic can be re-executed on rows that are inserted or changed by the running application.
Although the FCET is intended to be installed in the Patch Edition during an online patch, you can create and test an FCET in the Run Edition of a development database. To create an FCET, start with the Forward Crossedition Trigger Template and add the data upgrade logic to the trigger body.
The Forward Cross-edition Trigger Template is as follows:
REM ---- Create FCET ----
REM dbdrv: sql ~PROD ~PATH ~FILE \
REM dbdrv: none none none sqlplus &phase=ccet \
REM dbdrv: checkfile:~PROD:~PATH:~FILE &un_
REM ---- Apply FCET ----
REM dbdrv: sql ad patch/115/sql AD_ZD_TABLE_APPLY.sql \
REM dbdrv: none none none sqlplus &phase=acet \
REM dbdrv: checkfile:~PROD:~PATH:~FILE _F
REM Copyright (c) 2013 Oracle, All Rights Reserved
REM $Header$
REM _X.sql
REM
SET VERIFY OFF;
WHENEVER SQLERROR EXIT FAILURE ROLLBACK;
WHENEVER OSERROR EXIT FAILURE ROLLBACK;
create or replace trigger _F
before insert or update on &1..
for each row forward crossedition
/* follows */ disable
begin
end;
/
commit;
exit;
For our example, the FCET looks like the following:
REM ---- Create FCET ----
REM dbdrv: sql ~PROD ~PATH ~FILE \
REM dbdrv: none none none sqlplus &phase=ccet \
REM dbdrv: checkfile:~PROD:~PATH:~FILE &un_fnd
REM ---- Apply FCET ----
REM dbdrv: sql ad patch/115/sql AD_ZD_TABLE_APPLY.sql \
REM dbdrv: none none none sqlplus &phase=acet \
REM dbdrv: checkfile:~PROD:~PATH:~FILE:fcet XYZ_USER_SERVICE_F1
REM Copyright (c) 2013 Oracle Corporation, All Rights Reserved
REM $Header$
REM XYZ_USER_SERVICE_X1.sql
REM Update XYZ_USER_SERVICE SERVICE_TYPE to BRONZE/SILVER/GOLD
SET VERIFY OFF;
WHENEVER SQLERROR EXIT FAILURE ROLLBACK;
WHENEVER OSERROR EXIT FAILURE ROLLBACK;
create or replace trigger XYZ_USER_SERVICE_F1
before insert or update on &1..XYZ_USER_SERVICE
for each row forward crossedition
disable
begin
if :new.service_type = 'BASIC' then
:new.service_type#1 := 'BRONZE';
elsif :new.service_type = 'PREMIUM' then
:new.service_type#1 := 'GOLD';
end if;
end;
/
commit;
exit;
Create the trigger with the following naming standards:
Crossedition Trigger Script Name: _X.sql
is incremented for each successive patch to the table
Example: XYZ_USER_SERVICE_X1.sql, XYZ_USER_SERVICE_X2.sql, ...
Forward Crossedition Trigger Name: _F
Reverse Crossedition Trigger Name: _R
For custom (manual) patches, you use the script template and remove or ignore the "dbdrv" comments. Your database apply script will include commands to install and apply the FCET.
To unit test your crossedition trigger logic you can install and apply the trigger manually in the run edition of your development database. Execute the SQL script to create the trigger and then call the AD_ZD_TABLE_APPLY script to apply the trigger.
sqlplus @XYZ_USER_SERVICE_X1 APPLSYS
sqlplus @$AD_TOP/patch/115/sql/AD_ZD_TABLE_APPLY.sql XYZ_USER_SERVICE_F1
At this point the new column is populated. The final step of updating an existing logical column is to maintain any managed objects that may be referencing the original (now out-of-date) column. There may be indexes or materialized views that reference the physical table columns. If these objects reference obsolete table columns, they need to be updated to refer to the latest revised columns. This step can be done automatically by Online Patching.
To fix managed objects after revising an existing logical column, call the AD_ZD.FINALIZE, AD_ZD.CUTOVER and AD_ZD.CLEANUP procedures manually in your development database. These operations are normally done as part of the Online Patching Cycle, but since your development environment is not actually in an Online Patching Cycle, you must call the procedures manually.
sqlplus
exec ad_zd.finalize
exec ad_zd.cutover
exec ad_zd.cleanup
quit
The FINALIZE procedure creates a revised version of the index on SERVICE_TYPE. Since we are now storing the service type information in the SERVICE_TYPE#1 column, the existing index must be updated to use the new column. FINALIZE creates the revised index under an alternate name, which will be changed to the original name during the cutover phase.
The CUTOVER procedure removes the "NOT NULL" constraint on the old SERVICE_TYPE column, drops the old index, and renames the revised index to the original name. In a real Online Patch, the CUTOVER procedure also promotes the Patch Edition to be the new Run Edition, but when called from the Run Edition that action is skipped. The table is now ready for use.
The CLEANUP procedure disables and removes the crossedition trigger.
Extract the updated table definition from your development database.
For all instances on R12.AD.C.Delta.8 and higher, use the following command. Enter the password when prompted. Alternatively, you could pass the password on the command line but this method might be insecure:
perl xdfgen.pl XYZ_USER_SERVICE
For all instances on R12.AD.C.Delta.7:
perl xdfgen.pl / XYZ_USER_SERVICE
For single node database instances on R12.AD.C.Delta.6 and lower:
perl xdfgen.pl /@ XYZ_USER_SERVICE
For RAC instances on R12.AD.C.Delta.6 and lower:
perl xdfgen.pl /@ XYZ_USER_SERVICE
At last, you are ready to create the patch.
Create the patch.
Patch Files:
fnd/patch/115/xdf/xyz_user_service.xdf version 4
fnd/patch/115/sql/XYZ_USER_SERVICE_X1.sql
Manual apply phase actions for the file system:
cp fnd/patch/115/sql/* $FND_TOP/patch/115/sql
cp fnd/patch/115/xdf/* $FND_TOP/patch/115/xdf
Manual apply actions for the database:
For instances on R12.AD.C.Delta.8 and higher, use the following command. Enter the password when prompted. Alternatively, you could pass the password on the command line but this method might be insecure:
xdfcmp.pl $FND_TOP/patch/115/xdf/xyz_user_service.xdf
sqlplus @$FND_TOP/patch/115/sql/XYZ_USER_SERVICE_X1 APPLSYS
sqlplus @$AD_TOP/patch/115/sql/AD_ZD_TABLE_APPLY XYZ_USER_SERVICE_F1
For instances on R12.AD.C.Delta.7 and lower:
xdfcmp.pl /@$TWO_TASK $FND_TOP/patch/115/xdf/xyz_user_service.xdf /
sqlplus @$FND_TOP/patch/115/sql/XYZ_USER_SERVICE_X1 APPLSYS
sqlplus @$AD_TOP/patch/115/sql/AD_ZD_TABLE_APPLY XYZ_USER_SERVICE_F1
Test the patch.
When XDF applies the table update, the revised column and index is added, and the EV will be regenerated to use the new revised column. After the FCET is created and applied the revised column is populated with the new codes.
Multiple updates to the same table
Over time, you might need to make multiple changes to the structure or data of a particular table. Some of these change may require the use of additional revised columns and crossedition triggers. When the same table is patched with multiple crossedition triggers, the online patching tool requires that the order of trigger execution be explicitly defined. The previous FCET may have been applied in a previous patching session, but when multiple patches are merged into one rollup patch it will be the case that multiple crossedition for the same table are applied in the same patching cycle. In order to guarantee correct and predictable ordering of FCET execution, the database supports a "FOLLOWS" keyword in the trigger definition:
create or replace trigger XYZ_USER_SERVICE_F2
before insert or update on &1..xyz_user_service
for each row forward crossedition
FOLLOWS XYZ_USER_SERVICE_F1
disable
...
When multiple changes are made to the same table, each new FCET must be defined as following the previous FCET:
F1
F2 follows F1
F3 follows F2
... and so on ...
To continue our example, lets imagine that we are adding a new service level to our app and existing GOLD customers will automatically be promoted to the new level.
XYZ_USER_SERVICE
Name Null? Type
----------------------------------------- -------- --------------
USER_ID NOT NULL NUMBER
-- PK, FK to FND_USER.USER_ID
SERVICE_TYPE NOT NULL VARCHAR2(8)
-- 'BRONZE' - cheap service
-- 'SILVER' - plus service
-- 'GOLD' - best service
==> -- 'PLATINUM' - VIP
COMMENTS VARCHAR2(1000)
SERVICE_STATUS NOT NULL VARCHAR2(8)
-- 'ENABLED' - service is active
-- 'DISABLED' - service is not active.
Create the new column in your development database.
Again, we use a new revised column to hold the new service type values. Add a new revised column manually in your development database.
alter table APPLSYS.XYZ_USER_SERVICE
add (SERVICE_TYPE#2 varchar2(8) default '*NULL*' not null)
/
exec ad_zd_table.patch('APPLSYS', 'XYZ_USER_SERVICE')
Create a Forward Crossedition Trigger to populate the new column.
The FCET loads the new column with upgrade service type codes. The logic will promote existing GOLD customers to VIP level. Note that the logic in this FCET depends on XYZ_USER_SERVICE_F1 having run already. We indicate this dependency using the FOLLOWS clause.
REM ---- Create FCET ----
REM dbdrv: sql ~PROD ~PATH ~FILE \
REM dbdrv: none none none sqlplus &phase=ccet \
REM dbdrv: checkfile:~PROD:~PATH:~FILE &un_fnd
REM ---- Apply FCET ----
REM dbdrv: sql ad patch/115/sql AD_ZD_TABLE_APPLY.sql \
REM dbdrv: none none none sqlplus &phase=acet \
REM dbdrv: checkfile:~PROD:~PATH:~FILE:fcet XYZ_USER_SERVICE_F2
REM Copyright (c) 2013 Oracle Corporation, All Rights Reserved
REM $Header$
REM XYZ_USER_SERVICE_X2.sql
REM Populate XYZ_USER_SERVICE.SERVICE_TYPE
SET VERIFY OFF;
WHENEVER SQLERROR EXIT FAILURE ROLLBACK;
WHENEVER OSERROR EXIT FAILURE ROLLBACK;
create or replace trigger XYZ_USER_SERVICE_F2
before insert or update on &1..XYZ_USER_SERVICE
for each row forward crossedition
follows XYZ_USER_SERVICE_F1 /* notice! */
disable
begin
if :new.service_type#1 = 'GOLD' then
:new.service_type#2 := 'VIP';
else
:new.service_type#2 := :new.service_type#1;
end if;
end;
/
commit;
exit;
You can apply and test the FCET in the development database as follows:
sqlplus @XYZ_USER_SERVICE_X2 APPLSYS
# note: the trigger will create with compilation error, that is OK
sqlplus @$AD_TOP/patch/115/sql/AD_ZD_TABLE_APPLY XYZ_USER_SERVICE_F2
sqlplus
exec ad_zd.finalize
exec ad_zd.cutover
exec ad_zd.cleanup
quit
Note the following behavior: When the XYZ_USER_SERVICE_F2 trigger is initially created, it will not compile, because the trigger definition makes reference to XYZ_USER_SERVICE_F1 which no longer exists. This database behavior is corrected later by the APPLY procedure. When you execute the AD_ZD_TABLE_APPLY script, the new "F2" trigger will be enabled and applied to all existing rows, but since the XYZ_USER_SERVICE_F2 is defined as following XYZ_USER_SERVICE_F1, the APPLY procedure will automatically create an empty XYZ_USER_SERVICE_F1 trigger to satisfy the reference and allow "F2" to compile.
Extract the updated table definition from your development database:
For all instances on R12.AD.C.Delta.8 and higher, use the following command. Enter the password when prompted. Alternatively, you could pass the password on the command line but this method might be insecure:
perl xdfgen.pl XYZ_USER_SERVICE
For all instances on R12.AD.C.Delta.7:
perl xdfgen.pl / XYZ_USER_SERVICE
For single node database instances on R12.AD.C.Delta.6 and lower:
perl xdfgen.pl /@ XYZ_USER_SERVICE
For RAC instances on R12.AD.C.Delta.6 and lower:
perl xdfgen.pl /@ XYZ_USER_SERVICE
Create the patch.
Patch Files:
fnd/patch/115/xdf/xyz_user_service.xdf version 5
fnd/patch/115/sql/XYZ_USER_SERVICE_X2.sql
Manual apply phase actions for the file system:
cp fnd/patch/115/sql/* $FND_TOP/patch/115/sql
cp fnd/patch/115/xdf/* $FND_TOP/patch/115/xdf
Manual apply phase actions for the database:
For instances on R12.AD.C.Delta.8 and higher, use the following command. Enter the password when prompted. Alternatively, you could pass the password on the command line but this method might be insecure:
xdfcmp.pl $FND_TOP/patch/115/xdf/xyz_user_service.xdf
sqlplus @$FND_TOP/patch/115/sql/XYZ_USER_SERVICE_X2 APPLSYS
sqlplus @$AD_TOP/patch/115/sql/AD_ZD_TABLE_APPLY XYZ_USER_SERVICE_F2
For instances on R12.AD.C.Delta.7 and lower:
xdfcmp.pl /@$TWO_TASK $FND_TOP/patch/115/xdf/xyz_user_service.xdf /
sqlplus @$FND_TOP/patch/115/sql/XYZ_USER_SERVICE_X2 APPLSYS
sqlplus @$AD_TOP/patch/115/sql/AD_ZD_TABLE_APPLY XYZ_USER_SERVICE_F2
Test the patch.
When XDF applies the table update, the revised column and index will be added, and the EV will be regenerated to use the new revised column. After the FCET is created and applied the revised column will be populated with the new codes.
Migrate Data to a New Table
In some cases the database schema for a product is reorganized so that existing data rows must be moved to a newly delivered table. New or replacement tables might be required if you are making a change to data model cardinality (meaning a change to the number of rows used to store the same information). The editioning view and revised column technique allows the developer to change how entity attributes are stored in columns, but it does not allow for changing the number of rows in a existing table.
Replacement tables are delivered by XDF/ODF as usual, but these tables must be populated using forward crossedition triggers rather than traditional upgrade scripts. The following example shows how to deliver and populate a replacement table for an existing table.
Create the replacement table in your development database.
This is done exactly as delivering any other new table. In our example, we will create a replacement table for the WF_ITEMS table called WF_ITEMS_NEW.
create table APPLSYS.WF_ITEMS_NEW
(
NEW_ID NUMBER(15) not null,
ITEM_TYPE VARCHAR2(8) not null,
ITEM_KEY VARCHAR2(240) not null,
USER_KEY VARCHAR2(240)
)
tablespace APPS_TS_TX_DATA
/
-- new primary key
create unique index APPLSYS.WF_ITEMS_NEW_U1
on APPLSYS.WF_ITEMS_NEW ( NEW_ID )
tablespace APPS_TS_TX_IDX
/
-- this index is used for data migration
create unique index APPLSYS.WF_ITEMS_NEW_U2
on APPLSYS.WF_ITEMS_NEW ( ITEM_TYPE, ITEM_KEY )
tablespace APPS_TS_TX_IDX
/
Note that the replacement table must have indexing necessary for the data migration logic to efficiently map rows in source tables to the corresponding rows in the replacement table.
Create a LOAD_ROW procedure for the replacement table
The insert and update statements that populate a replacement table during data migration must be executed from a PL/SQL package, they CANNOT be directly executed by the data migration trigger itself. The reason for this is complicated, just accept it for now.
Create a PL/SQL package procedure that will execute the insert or update statements on the replacement table. These are best combined into a single procedure called LOAD_ROW that will accept the required attributes and then insert or update the row in the replacement table as needed.
create or replace package body WF_ITEMS_NEW_PKG as
procedure LOAD_ROW(
X_ITEM_TYPE in varchar2,
X_ITEM_KEY in varchar2,
X_USER_KEY in varchar2
) is
begin
insert into wf_items_new ( new_id, item_type, item_key, user_key )
values ( wf_items_new_s1.nextval, x_item_type, x_item_key, x_user_key );
exception when dup_val_on_index then
update wf_items_new
set user_key = x_user_key
where item_type = x_item_type
and item_key = x_item_key;
end;
end;
Create the data migration trigger
The data migration trigger is a forward crossedition trigger installed on the source table. This trigger will be fired for every row in the source table, and will also fire for any changes to the source table made by the running application. The migration trigger will call the LOAD_ROW procedure for the replacement table.
Once you migrate data from a source table into a replacement table, we expect that the source table is now obsolete and will no longer be patched. To indicate this, we use a standard name for data migration triggers which is
_FX
The 'X' indicates that this is the final crossedition trigger that will ever be created for that table.
If the source table had any previous crossedition triggers defined for it, then remember to specify the "follows " clause when you define the data migration trigger.
The "dbdrv" commands for a data migration trigger are just like an ordinary forward crossedition trigger with one exception. A forward crossedition trigger is normally applied in "&phase=acet". But a data migration trigger should be applied in "&phase=acet+1". By delaying execution of the data migration trigger we can ensure that any crossedition triggers on the destination table are already applied and therefore enabled.
REM ---- Create FCET ----
REM dbdrv: sql ~PROD ~PATH ~FILE \
REM dbdrv: none none none sqlplus &phase=ccet \
REM dbdrv: checkfile:~PROD:~PATH:~FILE &un_fnd
REM ---- Apply FCET ----
REM dbdrv: sql ad patch/115/sql AD_ZD_TABLE_APPLY.sql \
REM dbdrv: none none none sqlplus &phase=acet+1 \
REM dbdrv: checkfile:~PROD:~PATH:~FILE:fcet WF_ITEMS_FX
REM Copyright (c) 2016 Oracle Corporation, All Rights Reserved
REM $Header$ REM WF_ITEMS_FX.sql
REM Data Migration Example:
REM
REM Migrate rows in WF_ITEMS to replacement table WF_ITEMS_NEW
REM
REM Key mapping:
REM
REM WF_ITEMS (ITEM_TYPE,ITEM_KEY)
REM WF_ITEMS_NEW (ITEM_TYPE,ITEM_KEY)
REM
REM Data Mapping
REM -> WF_ITEM_NEW.NEW_ID
REM WF_ITEMS.ITEM_TYPE -> WF_ITEMS_NEW.ITEM_TYPE
REM WF_ITEMS.ITEM_KEY -> WF_ITEMS_NEW.ITEM_KEY
REM WF_ITEMS.USER_KEY -> WF_ITEMS_NEW.USER_KEY
REM
SET VERIFY OFF;
WHENEVER SQLERROR EXIT FAILURE ROLLBACK;
WHENEVER OSERROR EXIT FAILURE ROLLBACK;
create or replace trigger WF_ITEMS_FX
before insert or update or delete on &1..WF_ITEMS
for each row forward crossedition
/* follows */ disable
begin
if inserting or updating then
-- migrate data to new table
wf_items_new_pkg.load_row(:new.item_type, :new.item_key, :new.user_key);
elsif deleting then
-- Replicate delete to new table
delete from wf_items_new
where item_type = :old.item_type
and item_key = :old.item_key;
end if;
end;
/
commit;
exit;
IMPORTANT NOTE: For a data migration trigger, the apply phase should be "&phase=acet+1" rather than "@phase=acet". This is to guarentee that any future crossedition triggers on the destination table are enabled already before the data migration trigger is applied.
Patching rules for the replacement table
Initially, your replacement table will be brand new and have no revised columns, but you may decide to patch the structure of the replacement table in the future. If this occurs, you must take care to ensure that the original data migration trigger and LOAD_ROW logic will continue to work with the new replacement table structure. In particular, if you revise a not null or unique indexed column in the replacement table, then you must implement a reverse crossedition trigger to populate the old column using the same technique described for Seed Data Tables in the section "Update a Not Null or Unique Indexed Column".
Section 1.4.3.2: Seed Data Tables
Seed Data Tables must implement a special feature to support Online Patching called Editioned Data Storage. This feature allows a single seed data table to hold multiple copies of the seed data: During online patching, the original seed data remains in use by the Run Edition, and a separate copy of the data can be created for the Patch Edition. Editioned Data Storage allows a loader to modify the Patch Edition copy of seed data without affecting the Run Edition. Seed data tables are created and patched like ordinary tables with a few extra rules that will be explained presently.
Is your table really a seed data table? The extra patching standards and runtime overhead associated with seed data tables are best avoided, so please make sure that you do not upgrade a table to be a seed data table unless it is truly necessary. A real seed data table has ALL of the following properties:
The Table contains data that is "part of the application" and is delivered and maintained via application patching. More specifically:
You (the application developer) create and deliver data in the table.
You expect to maintain and patch the data along with the application code.
Typically, you have a seed data loader for the purpose of delivering data updates.
The Table Data affects runtime application functionality or appearance
Meaning the data is used by the code, rather than simply handled by the code. The data controls how the application operates.
Business Reference data such as Parties or Products is not seed data.
The Table Data is predominately application seed data.
There can be user-entered rows, but it is not appropriate to treat a high volume transaction table as a seed data table.
Sample transaction or setup data is not seed data.
Create a new Seed Data Table
In this example, we add a new seed data table to the application to hold "service type" information. The standard service types are created and maintained by application development, and so this table meets the definition of a seed data table. The logical table structure is as follows:
XYZ_SERVICE_TYPES
Name Null? Type
----------------------------------------- -------- --------------
SERVICE_TYPE NOT NULL VARCHAR2(8)
SERVICE_PRIORITY NOT NULL NUMBER
HOME_PAGE VARCHAR2(30)
Create the initial table definition in your development database.
This is done just like an ordinary table. Remember that seed data tables should be stored in the APPS_TS_SEED tablespace.
create table APPLSYS.XYZ_SERVICE_TYPES
(
SERVICE_TYPE VARCHAR2(8) not null,
SERVICE_PRIORITY NUMBER not null,
HOME_PAGE VARCHAR2(30)
)
tablespace APPS_TS_SEED
/
create unique index APPLSYS.XYZ_SERVICE_TYPES_U1
on APPLSYS.XYZ_SERVICE_TYPES ( SERVICE_TYPE )
tablespace APPS_TS_SEED
/
exec ad_zd_table.upgrade('APPLSYS', 'XYZ_SERVICE_TYPES')
Upgrade table to support Editioned Data Storage.
This is a new required step for seed data tables and is done by calling the AD_ZD_SEED.UPGRADE procedure.
exec ad_zd_seed.upgrade('XYZ_SERVICE_TYPES')
Now the table is officially a Seed Data Table. The AD_ZD_SEED.UPGRADE procedure added a new column to the table key that stripes the data by edition, along with various supporting objects. The loader for a seed data table must be coded to call the AD_ZD_SEED.PREPARE procedure before changing the content of the table in an Online Patch, but no special action is required to update the table from the Run Edition. For this example, we can just put in some sample data directly.
insert into XYZ_SERVICE_TYPES (service_type, service_priority, home_page)
values ('VIP', 0, 'VIP_HOME');
insert into XYZ_SERVICE_TYPES (service_type, service_priority, home_page)
values ('GOLD', 1, 'GOLD_HOME');
insert into XYZ_SERVICE_TYPES (service_type, service_priority, home_page)
values ('SILVER', 2, 'SILVER_HOME');
insert into XYZ_SERVICE_TYPES (service_type, service_priority, home_page)
values ('BRONZE', 3, 'BRONZE_HOME');
commit;
Create a loader for the seed data table:
The Seed Data Loader is typically implemented as a loader configuration file (LCT) for the FNDLOAD generic loader. This is created in the usual way, with one new addition, which is to define the tables that must be prepared when seed data is patched using the loader. Here is a simple LCT definition for the example table:
COMMENT = "dbdrv: exec fnd bin FNDLOAD bin &phase=daa checkfile:~PROD:~PATH:~FILE &ui_apps 0 Y UPLOAD @FND:patch/115/import/xyzst.lct @~PROD:~PATH/~FILE"
DEFINE XYZ_SERVICE_TYPE
KEY SERVICE_TYPE VARCHAR2(8)
BASE SERVICE_PRIORITY VARCHAR2(8)
BASE HOME_PAGE VARCHAR2(30)
END XYZ_SERVICE_TYPE
DOWNLOAD XYZ_SERVICE_TYPE
" select SERVICE_TYPE, to_char(SERVICE_PRIORITY), HOME_PAGE
from XYZ_SERVICE_TYPES
where (:SERVICE_TYPE is null or SERVICE_TYPE like :SERVICE_TYPE) "
UPLOAD XYZ_SERVICE_TYPE
" begin
update XYZ_SERVICE_TYPES
set SERVICE_PRIORITY = :SERVICE_PRIORITY,
HOME_PAGE = :HOME_PAGE
where SERVICE_TYPE = :SERVICE_TYPE;
if SQL%NOTFOUND then
insert into XYZ_SERVICE_TYPES
( SERVICE_TYPE, SERVICE_PRIORITY, HOME_PAGE )
values (:SERVICE_TYPE, to_number(:SERVICE_PRIORITY), :HOME_PAGE);
end if;
end; "
PREPARE XYZ_SERVICE_TYPE
TABLE XYZ_SERVICE_TYPES
Notice the PREPARE statement at the end of the file. This statement tells the loader to prepare the 'XYZ_SERVICE_TYPES' table before attempting to load data for the XYZ_SERVICE_TYPE entity.
Extract the table definition from your development database:
For all instances on R12.AD.C.Delta.8 and higher, use the following command. Enter the password when prompted. Alternatively, you could pass the password on the command line but this method might be insecure:
perl xdfgen.pl XYZ_SERVICE_TYPES
For all instances on R12.AD.C.Delta.7:
perl xdfgen.pl / XYZ_SERVICE_TYPES
For single node database instances on R12.AD.C.Delta.6 and lower:
perl xdfgen.pl /@ XYZ_SERVICE_TYPES
For RAC instances on R12.AD.C.Delta.6 and lower::
perl xdfgen.pl /@ XYZ_SERVICE_TYPES
Extract starting seed data from your development database:
FNDLOAD 0 Y DOWNLOAD xyzst.lct xyzst_data.ldt XYZ_SERVICE_TYPE
Enter the password when prompted.
Create the patch.
Patch Files:
fnd/patch/115/xdf/xyz_service_types.xdf
fnd/patch/115/import/xyzst.lct
fnd/patch/115/import/US/xyzst_data.ldt
Manual apply phase actions for the file system:
cp fnd/patch/115/xdf/* $FND_TOP/patch/115/xdf
cp fnd/patch/115/import/* $FND_TOP/patch/115/import
cp fnd/patch/115/import/US/* $FND_TOP/patch/115/import/US
Manual apply phase actions for the database for instances on R12.AD.C.Delta.8 and higher. Enter the passwords when prompted:
xdfcmp.pl $FND_TOP/patch/115/xdf/xyz_service_types.xdf
FNDLOAD 0 Y UPLOAD $FND_TOP/patch/115/import/xyzst.lct $FND_TOP/patch/115/import/US/xyzst_data.ldt
Manual apply phase actions for the database for instances on R12.AD.C.Delta.7 and lower:
xdfcmp.pl /@$TWO_TASK $FND_TOP/patch/115/xdf/xyz_service_types.xdf /
FNDLOAD 0 Y UPLOAD $FND_TOP/patch/115/import/xyzst.lct $FND_TOP/patch/115/import/US/xyzst_data.ldt
Test the patch.
When the patch is applied, XDF first creates the initial table, and then automatically calls AD_ZD_TABLE.UPGRADE. XDF also detects that the table definition is for a seed data table, and calls the AD_ZD_SEED.UPGRADE procedure to install supporting objects for Editioned Data Storage.
Once the seed data table is in place, the FNDLOAD procedure will load data into the table. The loader will automatically call the AD_ZD_SEED.PREPARE procedure for table to be loaded (although in this case the procedure will not do anything as there is no run edition copy of seed data).
When the patch is complete, verify that the seed data table definition and contents are as expected.
Update a NOT NULL or Unique Indexed Column
If you patch an existing column in a seed data table that either (a) has a NOT NULL constraint with no default value, or (b) is part of a unique index, there is a new requirement: In addition to writing the Forward Crossedition Trigger to populate your revised column: You also need to code a Reverse Crossedition Trigger to populate the original column when data is loaded in the Patch Edition. For example, suppose we need to increase the size of the SERVICE_TYPE column from 8 to 30 bytes:
XYZ_SERVICE_TYPES
Name Null? Type
----------------------------------------- -------- --------------
==> SERVICE_TYPE NOT NULL VARCHAR2(30)
SERVICE_PRIORITY NOT NULL NUMBER
HOME_PAGE VARCHAR2(30)
Create the revised column in your development database.
alter table APPLSYS.XYZ_SERVICE_TYPES
add (SERVICE_TYPE#1 varchar2(30) default '*NULL*' not null)
/
exec ad_zd_table.patch('APPLSYS', 'XYZ_SERVICE_TYPES')
Create a Forward Crossedition Trigger to populate the revised column.
This is identical to the technique used for ordinary tables. However, the SQL script that creates the FCET will also create and apply a Reverse Crossedition Trigger.
Create a Reverse Crossedition Trigger to populate the original column.
The reverse crossedition trigger only fires when the table contents is changed from the patch edition (such as during seed data loading). The purpose of the of the Reverse Crossedition Trigger is to populate the old column in some way that satisfies the old NOT NULL or UNIQUE constraint. Following is an example of SQL script that combines creation of both the FCET and RCET for a revised unique indexed column.
REM ---- Create FCET+RCET ----
REM dbdrv: sql ~PROD ~PATH ~FILE \
REM dbdrv: none none none sqlplus &phase=ccet \
REM dbdrv: checkfile:~PROD:~PATH:~FILE &un_fnd
REM ---- Apply FCET ----
REM dbdrv: sql ad patch/115/sql AD_ZD_TABLE_APPLY.sql \
REM dbdrv: none none none sqlplus &phase=acet \
REM dbdrv: checkfile:~PROD:~PATH:~FILE:fcet XYZ_SERVICE_TYPES_F1
REM ---- Apply RCET ----
REM dbdrv: sql ad patch/115/sql AD_ZD_TABLE_APPLY.sql \
REM dbdrv: none none none sqlplus &phase=acet \
REM dbdrv: checkfile:~PROD:~PATH:~FILE:rcet XYZ_SERVICE_TYPES_R1
REM Copyright (c) 2013 Oracle Corporation, All Rights Reserved
REM $Header$
REM XYZ_SERVICE_TYPES_X1.sql
REM Update XYZ_SERVICE_TYPES.SERVICE_TYPE to varchar2(30)
SET VERIFY OFF;
WHENEVER SQLERROR EXIT FAILURE ROLLBACK;
WHENEVER OSERROR EXIT FAILURE ROLLBACK;
-- FCET Definition
create or replace trigger XYZ_SERVICE_TYPES_F1
before insert or update on &1..XYZ_SERVICE_TYPES
for each row forward crossedition
disable
begin
:new.service_type#1 := :new.service_type;
end;
/
-- RCET Definition
create or replace trigger XYZ_SERVICE_TYPES_R1
before insert or update on &1..XYZ_SERVICE_TYPES
for each row reverse crossedition
disable
begin
:new.service_type := substrb(:new.service_type#1, 1, 8);
end;
/
commit;
exit;
You might have noticed that the example reverse crossedition trigger logic may not satisfy the uniqueness constraint of the old column for new data that is longer than 8 bytes. In cases where this is a concern, you can populate the old column with values from a sequence number, converted to an 8-byte string. The reverse crossedition trigger does not actually need to populate meaningful data in the old columns, it only needs ensure that database constraints on the old column are satisfied when rows are loaded in the patch edition.
You can apply and test the FCET/RCET triggers in a development database as follows:
sqlplus @XYZ_SERVICE_TYPES_X1 APPLSYS
sqlplus @$AD_TOP/patch/115/sql/AD_ZD_TABLE_APPLY XYZ_SERVICE_TYPES_F1
sqlplus @$AD_TOP/patch/115/sql/AD_ZD_TABLE_APPLY XYZ_SERVICE_TYPES_R1
sqlplus
exec ad_zd.finalize
-- test insert into table
insert into XYZ_SERVICE_TYPES
(service_type, service_priority, home_page)
values ('TEST_TYPE', 0, 'TEST');
select * from applsys.xyz_service_types
where service_type#1 = 'TEST_TYPE';
rollback;
exec ad_zd.cutover
exec ad_zd.cleanup
Since the reverse crossedition trigger is not applied to existing rows of the table, It is recommended that you make a test insert into the table in order to verify the trigger logic.
Extract the table definition from your development database:
For all instances on R12.AD.C.Delta.8 and higher, use the following command. Enter the password when prompted. Alternatively, you could pass the password on the command line but this method might be insecure:
perl xdfgen.pl XYZ_SERVICE_TYPES
For all instances on R12.AD.C.Delta.7:
perl xdfgen.pl / XYZ_SERVICE_TYPES
For single node database instances on R12.AD.C.Delta.6 and lower:
perl xdfgen.pl /@ XYZ_SERVICE_TYPES
For RAC instances on R12.AD.C.Delta.6 and lower:
perl xdfgen.pl /@ XYZ_SERVICE_TYPES
Create the patch.
Patch Files:
fnd/patch/115/xdf/xyz_service_types.xdf
fnd/patch/115/sql/XYZ_SERVICE_TYPES_X1.sql
fnd/patch/115/import/xyzst.lct
Manual apply phase actions for the file system:
cp fnd/patch/115/xdf/* $FND_TOP/patch/115/xdf
cp fnd/patch/115/sql/* $FND_TOP/patch/115/sql
cp fnd/patch/115/import/* $FND_TOP/patch/115/import
Manual apply phase actions for the database for instances on R12.AD.C.Delta.8 and higher. Enter the password when prompted. Alternatively, you could pass the password on the command line but this method might be insecure:
xdfcmp.pl $FND_TOP/patch/115/xdf/xyz_service_types.xdf
sqlplus @$FND_TOP/patch/115/sql/XYZ_SERVICE_TYPES_X1 APPLSYS
sqlplus @$AD_TOP/patch/115/sql/AD_ZD_TABLE_APPLY XYZ_SERVICE_TYPES_F1
sqlplus @$AD_TOP/patch/115/sql/AD_ZD_TABLE_APPLY XYZ_SERVICE_TYPES_R1
Manual apply phase actions for the database for instances on R12.AD.C.Delta.7 and lower. Enter the password when prompted:
xdfcmp.pl /@$TWO_TASK $FND_TOP/patch/115/xdf/xyz_service_types.xdf /
sqlplus @$FND_TOP/patch/115/sql/XYZ_SERVICE_TYPES_X1 APPLSYS
sqlplus @$AD_TOP/patch/115/sql/AD_ZD_TABLE_APPLY XYZ_SERVICE_TYPES_F1
sqlplus @$AD_TOP/patch/115/sql/AD_ZD_TABLE_APPLY XYZ_SERVICE_TYPES_R1
Test the patch.
When applied to a patch edition, XDF creates the new revised column and index. Then the crossedition triggers will be installed. The FCET will populate the new revised column. The RCET will populate the old column if any data is loaded into the table in the patch edition. After cutover, the old index and crossedition triggers will be removed.
Section 1.4.3.3: Multiple updates to the same seed data table
As mentioned in the preceding section for Tables, when you make second and subsequent updates to the same table, each new Forward Crossedition Trigger must be created so that it FOLLOWS the previous FCET. This rule applies to seed data tables as well, but seed data tables have an additional requirement to specify ordering for the second and subsequent Reverse Crossedition Triggers. Each new RCET must be created so that it PRECEDES the previous RCET, if any. The PRECEDES syntax looks like this:
create or replace trigger XYZ_SERVICE_TYPES_R2
before insert or update on &1..xyz_user_service
for each row reverse crossedition
PRECEDES XYZ_SERVICE_TYPES_R1
disable
...
So each new FCET FOLLOWS the previous FCET.
F1
F2 follows F1 ...
F3 follows F2 ...
... and so on ...
And each new RCET PRECEDES the previous RCET.
R1
R2 precedes R1 ...
R3 precedes R2 ...
... and so on ...
For our coding example, let us simply make a null change to the primary key column to demonstrate the technique:
XYZ_SERVICE_TYPES
Name Null? Type
----------------------------------------- -------- --------------
SERVICE_TYPE NOT NULL VARCHAR2(30)
SERVICE_PRIORITY NOT NULL NUMBER
HOME_PAGE VARCHAR2(30)
Create the revised column in your development database.
alter table APPLSYS.XYZ_SERVICE_TYPES
add (SERVICE_TYPE#2 varchar2(30) default '*NULL*' not null)
/
exec ad_zd_table.patch('APPLSYS', 'XYZ_SERVICE_TYPES')
Create a Forward Crossedition Trigger to populate the revised column.
The new FCET must be created so that it FOLLOWS the previous FCET.
Create a Reverse Crossedition Trigger to populate the original column.
The new RCET must be created so that it PRECEDES the previous RCET.
REM ---- Create FCET+RCET ----
REM dbdrv: sql ~PROD ~PATH ~FILE \
REM dbdrv: none none none sqlplus &phase=ccet \
REM dbdrv: checkfile:~PROD:~PATH:~FILE &un_fnd
REM ---- Apply FCET ----
REM dbdrv: sql ad patch/115/sql AD_ZD_TABLE_APPLY.sql \
REM dbdrv: none none none sqlplus &phase=acet \
REM dbdrv: checkfile:~PROD:~PATH:~FILE:fcet XYZ_SERVICE_TYPES_F2
REM ---- Apply RCET ----
REM dbdrv: sql ad patch/115/sql AD_ZD_TABLE_APPLY.sql \
REM dbdrv: none none none sqlplus &phase=acet \
REM dbdrv: checkfile:~PROD:~PATH:~FILE:rcet XYZ_SERVICE_TYPES_R2
REM Copyright (c) 2013 Oracle Corporation, All Rights Reserved
REM $Header$
REM XYZ_SERVICE_TYPES_X2.sql
REM Pretend update to XYZ_SERVICE_TYPES.SERVICE_TYPE attribute
SET VERIFY OFF;
WHENEVER SQLERROR EXIT FAILURE ROLLBACK;
WHENEVER OSERROR EXIT FAILURE ROLLBACK;
-- FCET Definition
create or replace trigger XYZ_SERVICE_TYPES_F2
before insert or update on &1..xyz_service_types
for each row forward crossedition
follows XYZ_SERVICE_TYPES_F1
disable
begin
:new.service_type#2 := :new.service_type#1;
end;
/
-- RCET Definition
create or replace trigger XYZ_SERVICE_TYPES_R2
before insert or update on &1..xyz_service_types
for each row reverse crossedition
precedes XYZ_SERVICE_TYPES_R1
disable
begin
:new.service_type#1 := :new.service_type#2;
end;
/
commit;
exit;
Apply and test the FCET/RCET triggers in a development database as follows:
sqlplus @XYZ_SERVICE_TYPES_X2 APPLSYS
# both triggers create with compilation errors, no worries.
sqlplus @$AD_TOP/patch/115/sql/AD_ZD_TABLE_APPLY XYZ_SERVICE_TYPES_F2
sqlplus @$AD_TOP/patch/115/sql/AD_ZD_TABLE_APPLY XYZ_SERVICE_TYPES_R2
sqlplus
exec ad_zd.finalize
-- test insert into table
insert into XYZ_SERVICE_TYPES
(service_type, service_priority, home_page)
values ('TEST_TYPE', 0, 'TEST');
select * from applsys.xyz_service_types
where service_type#1 = 'TEST_TYPE';
rollback;
exec ad_zd.cutover
exec ad_zd.cleanup
Extract the table definition from your development database:
For all instances on R12.AD.C.Delta.8 and higher, use the following command. Enter the password when prompted. Alternatively, you could pass the password on the command line but this method might be insecure::
perl xdfgen.pl XYZ_SERVICE_TYPES
For all instances on R12.AD.C.Delta.7:
perl xdfgen.pl / XYZ_SERVICE_TYPES
For single node database instances on R12.AD.C.Delta.6 and lower:
perl xdfgen.pl /@ XYZ_SERVICE_TYPES
For RAC instances on R12.AD.C.Delta.6 and lower:
perl xdfgen.pl /@ XYZ_SERVICE_TYPES
Create the patch.
Patch Files:
fnd/patch/115/xdf/xyz_service_types.xdf
fnd/patch/115/sql/XYZ_SERVICE_TYPES_X2.sql
Manual apply phase actions for the file system:
cp fnd/patch/115/xdf/* $FND_TOP/patch/115/xdf
cp fnd/patch/115/sql/* $FND_TOP/patch/115/sql
Manual apply phase actions for the database for instances on R12.AD.C.Delta.8 and higher. Enter the passwords when prompted:
xdfcmp.pl $FND_TOP/patch/115/xdf/xyz_service_types.xdf
sqlplus @$FND_TOP/patch/115/sql/XYZ_SERVICE_TYPES_X2 APPLSYS
sqlplus @$AD_TOP/patch/115/sql/AD_ZD_TABLE_APPLY XYZ_SERVICE_TYPES_F2
sqlplus @$AD_TOP/patch/115/sql/AD_ZD_TABLE_APPLY XYZ_SERVICE_TYPES_R2
Manual apply phase actions for the database for instances on R12.AD.C.Delta.7 and lower:
xdfcmp.pl /@$TWO_TASK $FND_TOP/patch/115/xdf/xyz_service_types.xdf /
sqlplus @$FND_TOP/patch/115/sql/XYZ_SERVICE_TYPES_X2 APPLSYS
sqlplus @$AD_TOP/patch/115/sql/AD_ZD_TABLE_APPLY XYZ_SERVICE_TYPES_F2
sqlplus @$AD_TOP/patch/115/sql/AD_ZD_TABLE_APPLY XYZ_SERVICE_TYPES_R2
Section 1.4.3.4: Temporary Tables
A global temporary table is a table that does not have permanent storage. Rows in a temporary table are held in memory either for a single transaction or for a single session, and are not accessible outside of the current session. Temporary tables are normally used to hold interim or summarized results in order to improve the performance of some other processing.
A global temporary table is a non-editioned object with a special restriction compared to ordinary tables: A temporary table cannot be modified in any way during online patching. This is a database restriction: attempting to modify a temporary table while it is in use by any other session will result in an oracle error such as "ORA-14450: attempt to access a transactional temp table already in use". Therefore, patching a temporary table definition requires a special procedure.
Create a Temporary Table
To create and deliver the first version of a temporary table, you create the table in your development environment, extract it using XDF, and include the XDF in your patch. This process should be the same as it was in classic downtime patching.
Create the temporary table in a development database. This is done using standard SQL*Plus. For example:
create global temporary table APPLSYS.XYZ_USER_GT
(
USER_ID NUMBER(15) not null,
USER_DATA VARCHAR2(10)
)
/
create index APPLSYS.XYZ_USER_GT_N1 on APPLSYS.XYZ_USER_GT (USER_ID)
/
create or replace synonym XYZ_USER_GT for APPLSYS.XYZ_USER_GT2;
Note that the temporary table must be created in a product schema, not directly in the APPS schema. The APPS schema must contain a synonym that points to the temporary table, which will serve as the permanent logical name of the temporary table. When the temporary table is be patched in the future, you will create a new temporary table with a different name but the logical name (APPS synonym) will stay the same.
It is possible to create indexes on a temporary table. The index information will be included when you extract the definition with XDF.
After manual creation, you should validate that the temporary table definition is correct and works as expected.
Extract the temporary table definition to an XDF file. This is done as follows:
For all instances on R12.AD.C.Delta.8 and higher, use the following command. Enter the password when prompted. Alternatively, you could pass the password on the command line but this method might be insecure:
perl xdfgen.pl XYZ_USER_GT
For all instances on R12.AD.C.Delta.7:
perl xdfgen.pl / XYZ_USER_GT
For single node database instances on R12.AD.C.Delta.6 and lower:
perl xdfgen.pl /@ XYZ_USER_GT
For RAC instances on R12.AD.C.Delta.6 and lower:
perl xdfgen.pl /@ XYZ_USER_GT
Create the patch.
Patch Files:
fnd/patch/115/xdf/xyz_user_gt.xdf
Manual apply phase actions for the file system:
cp fnd/patch/115/xdf/* $FND_TOP/patch/115/xdf
Manual apply phase actions for the database for instances on R12.AD.C.Delta.8 and higher. Enter the password when prompted. Alternatively, you could pass the password on the command line but this method might be insecure:
xdfcmp.pl $FND_TOP/patch/115/xdf/xyz_user_gt.xdf
Manual apply phase actions for the database: for instances on R12.AD.C.Delta.7 and lower:
xdfcmp.pl /@$TWO_TASK $FND_TOP/patch/115/xdf/xyz_user_gt.xdf /
Revise an existing Temporary Table
When making any structural change to a temporary table or its indexes, it is not possible to alter the existing temporary table in place. Instead, you must create a new temporary table with a different name, and change the existing APPS synonym to point at the new table.
Create the revised temporary table in a development database. This is done using standard SQL*Plus. For example
create global temporary table APPLSYS.XYZ_USER_GT2
(
USER_ID NUMBER(15) not null,
JOB_TYPE VARCHAR2(8) not null,
USER_DATA VARCHAR2(10)
)
/
drop index APPLSYS.XYZ_USER_GT_N1;
create index APPLSYS.XYZ_USER_GT_N1
on APPLSYS.XYZ_USER_GT2 (USER_ID, JOB_TYPE);
create or replace synonym XYZ_USER_GT for APPLSYS.XYZ_USER_GT2;
You can keep indexes with their original names, even though the name of the underling temporary table has changed.
After this manual creation, you should validate that the revised temporary table definition is correct and works as expected.
Extract the temporary table definition to an XDF file using the original file name.
Run xdfgen.pl on the APPS synonym for the temporary table. Do not use the actual temporary table name. By using the APPS synonym, you allow XDF to record information about the link between the synonym and the new temporary table.
Warning: If your instance is on R12.AD.C.Delta.6 or lower, you will need to ensure that a temporary table with a name matching the APPS synonym exists in addition to the revised temporary table that you are trying to extract. You do not need to do this with R12.AD.C.Delta.7 or higher.
For all instances on R12.AD.C.Delta.8 and higher, use the following command. Enter the password when prompted. Alternatively, you could pass the password on the command line but this method might be insecure:
perl xdfgen.pl XYZ_USER_GT
For all instances on R12.AD.C.Delta.7:
perl xdfgen.pl / XYZ_USER_GT
For single node database instances on R12.AD.C.Delta.6 and lower:
perl xdfgen.pl /@ XYZ_USER_GT
For RAC instances on R12.AD.C.Delta.6 and lower:
perl xdfgen.pl /@ XYZ_USER_GT
When the extracted XDF is applied to a target system, XDF will automatically do the following:
Create the revised temporary table
Create the revised indexes using an alternate name
Change the original APPS table synonym to point to the revised temporary table in the patch edition.
Submit a deferred CLEANUP DDL to drop the old temporary table during the cleanup phase.
Create the patch.
Patch Files:
fnd/patch/115/xdf/xyz_user_gt.xdf
Manual apply phase actions for the file system:
cp fnd/patch/115/xdf/* $FND_TOP/patch/115/xdf
Manual apply phase actions for the database for instances on R12.AD.C.Delta.8 and higher. Enter the password when prompted. Alternatively, you could pass the password on the command line but this method might be insecure:
xdfcmp.pl $FND_TOP/patch/115/xdf/xyz_user_gt.xdf
Manual apply phase actions for the database for instances on R12.AD.C.Delta.7 and lower:
xdfcmp.pl /@$TWO_TASK $FND_TOP/patch/115/xdf/xyz_user_gt.xdf /
Test the patch.
When the XDF is applied to the patch edition, XDF will create the revised temporary table and index (using an alternate name for the indexes). XDF will then change the Patch Edition APPS table synonym to point to the revised temporary table. In the Run Edition, the APPS table synonym continues to point at the original temporary table, which remains undisturbed. XDF also submits a deferred CLEANUP DDL to drop the old temporary table during the cleanup phase. During cutover, the old index is dropped and the new index is renamed to the specified name. During CLEANUP the deferred DDL is executed to drop the old temporary table.
Section 1.4.3.5: Materialized Views
In Oracle Database Release 11g Release 2 (11.2), a materialized view definition may not reference editioned objects. However, application developers must define the materialized view query in terms of APPS table synonyms and views which are editioned objects. To work around the restriction on materialized views, the Oracle E-Business Suite Online Patching solution supports a new Effectively-Editioned Materialized View compound object. The developer-specified query is stored in an ordinary view, called the Logical View. The materialized view is then generated from the logical view, using a new database feature that translates the logical query into an equivalent "implementation query" which depends only on non-editioned objects.
In Oracle Database 12c Release 1 (12.1) and later it is possible to create a native materialized view definition that references editioned objects by using the "EVALUATE USING CURRENT EDITION" clause in the create statement. Customers on Oracle Database 12.1 or later can use this approach to create custom materialized views, and in doing so, can avoid the special development procedures described immediately below; instead, they can review the subsequent section, Creating and Changing Custom Materialized Views on Oracle Database 12c. Consult the Oracle Database SQL Language Reference for more information. The Oracle E-Business Suite Online Patching tool will automatically alter the evaluation edition of materialized views to the run edition during online patching cutover. Note: Oracle E-Business Suite shipped products support operation on Oracle Database Release 11.2 and thus do not use the evaluation edition feature.
This section describes how to work with the effectively-editioned materialized view compound object.
Create a new Materialized View
On an editioned database, you can no longer create a materialized view directly.
Create the Logical View in your development database.
The Logical View is an ordinary database view that implements the desired query. The Logical View name must be the desired materialized view name with a '#' character appended to it. In this example, we intend to create a materialized view called XYZ_SCHEMAS_MV that presents some information about the database schemas associated with Oracle E-Business Suite. We start by creating the logical view XYZ_SCHEMAS_MV#:
create or replace view XYZ_SCHEMAS_MV# as
select upper(oracle_username) USERNAME,
decode(read_only_flag,
'C', 'pub', 'E', 'applsys', 'U', 'apps') USERTYPE
from fnd_oracle_userid
where read_only_flag in ('C', 'E', 'U');
While it is acceptable for the logical view to depend on editioned synonyms and views, it must not depend on editioned PL/SQL functions, such as those in the Oracle E-Business Suite APPS schema (built-in PL/SQL functions such as "upper" are acceptable). Test the Logical View to ensure that its shape and results are correct.
select * from XYZ_SCHEMAS_MV#;
USERNAME USERTYP
------------------------------ -------
APPLSYS applsys
APPS apps
APPLSYSPUB pub
Generate the Materialized View.
On an editioned database, materialized views are generated from their corresponding logical views using the AD_ZD_MVIEW.UPGRADE procedure.
exec ad_zd_mview.upgrade('APPS', 'XYZ_SCHEMAS_MV')
In this example, the UPGRADE procedure detects that materialized view is missing and generates it from the Logical View. The Materialized View definition is generated by transforming the Logical View query into an equivalent implementation query that directly references the underlying tables and columns. You can see the resulting MV implementation objects using the "ADZDSHOWMV" utility script:
sqlplus @ADZDSHOWMV XYZ_SCHEMAS_MV
-- MV Objects
OBJECT_NAME OBJECT_TYPE STATUS DESCRIPTION
------------------------------ ------------------- ---------- -------------------
XYZ_SCHEMAS_MV MATERIALIZED VIEW VALID Materialized View
XYZ_SCHEMAS_MV TABLE VALID Container Table
XYZ_SCHEMAS_MV# VIEW VALID Logical View
-- MV Properties
MV_NAME REFERS REFRESH_ STALENESS
------------------------------ ------ -------- -------------------
XYZ_SCHEMAS_MV DEMAND FORCE FRESH
The MV implementation query should never be changed directly. It must always be generated from the logical view using the UPGRADE procedure. The MV implementation query can be difficult to read and normally the developer will not need to look at it. But it is worth examining the implementation query of our example to understand what the transformation is doing. The formatted MV implementation query for our example logical view is as follows:
CREATE MATERIALIZED VIEW "APPS"."XYZ_SCHEMAS_MV"
("USERNAME", "USERTYPE") AS
SELECT
UPPER("A1"."ORACLE_USERNAME") "USERNAME",
DECODE("A1"."READ_ONLY_FLAG",
'C','pub','E','applsys','U','apps') "USERTYPE"
FROM "APPLSYS"."FND_ORACLE_USERID" "A1"
WHERE "A1"."READ_ONLY_FLAG"='C'
OR "A1"."READ_ONLY_FLAG"='E'
OR "A1"."READ_ONLY_FLAG"='U'
Notice that while the logical view references the APPS FND_ORACLE_USERID table synonym, the materialized view references the base table directly. The generated MV is automatically maintained by online patching whenever the logical view or anything it depends on is changed in a patch. Once generated, you can query or refresh the MV as usual.
select * from XYZ_SCHEMAS_MV;
USERNAME USERTYP
------------------------------ -------
APPLSYS applsys
APPS apps
APPLSYSPUB pub
Extract the MV definition using XDF.
Once the generated MV has been tested, you can extract the definition using XDF. XDF has been extended to automatically substitute the MV Logical View query for the implementation query in extracting an MV definition.
For all instances on R12.AD.C.Delta.8 and higher, use the following command. Enter the password when prompted. Alternatively, you could pass the password on the command line but this method might be insecure:
perl xdfgen.pl XYZ_SCHEMAS_MV
For all instances on R12.AD.C.Delta.7:
perl xdfgen.pl / XYZ_SCHEMAS_MV
For single node database instances on R12.AD.C.Delta.6 and lower:
perl xdfgen.pl /@ XYZ_SCHEMAS_MV
For RAC instances on R12.AD.C.Delta.6 and lower:
perl xdfgen.pl /@ XYZ_SCHEMAS_MV
Create the patch.
Patch Files:
fnd/patch/115/xdf/xyz_schemas_mv.xdf
Manual apply phase actions for the file system:
cp fnd/patch/115/xdf/* $FND_TOP/patch/115/xdf
Manual apply phase actions for the database for instances on R12.AD.C.Delta.8 and higher. Enter the password when prompted. Alternatively, you could pass the password on the command line but this method might be insecure:
xdfcmp.pl $FND_TOP/patch/115/xdf/xyz_schemas_mv.xdf
Manual apply phase actions for the database for instances on R12.AD.C.Delta.7 and lower:
xdfcmp.pl /@$TWO_TASK $FND_TOP/patch/115/xdf/xyz_schemas_mv.xdf
Note that unlike tables, the MV definition is applied in the APPS schema, so the xdfcmp.pl syntax is slightly different.
Test the patch.
When the XDF file is applied on a target database, XDF will automatically create the Logical View and then use the UPGRADE procedure to generated the Materialized View on the target database. The generated materialized view query will vary depending on the definitions of the objects that the Logical View depends on in the specific target database. In this case, the created MV is new (does not already exist in the target database) so XDF creates the MV immediately. The case of changing an existing MV is covered in the next section.
Change a Materialized View
To change an existing materialized view in a development database, the developer will replace the Logical View with an updated definition and then regenerate the Materialized View implementation. The patching procedure is the same.
Replace the Logical View in your development database.
To change the definition of a materialized view, you first replace the definition of the corresponding logical view in your development database. This is done using SQL DDL as usual. In this example, we create a new view that our MV definition will reference, and then update the XYZ_SCHEMAS_MV# Logical View to use the new view. When you are satisfied with the results of the updated Logical View, remember to call the AD_ZD_MVIEW.UPGRADE procedure to regenerate materialized view implementation.
/* new view for schema type information - xyz_schema_types.sql */
create or replace view XYZ_SCHEMA_TYPES as
select lv.lookup_code CODE
, lv.meaning MEANING
from fnd_lookup_values lv
where lv.lookup_type = 'ORACLEID_PRIVILEGE_INVIS'
and lv.language = 'US';
/* change XYZ_SCHEMAS_MV logical view to use XYZ_SCHEMA_TYPES view */
create or replace view XYZ_SCHEMAS_MV# as
select fou.oracle_username USERNAME
, st.meaning USERTYPE
from fnd_oracle_userid fou, xyz_schema_types st
where fou.read_only_flag in ('C', 'E', 'U')
and st.code = fou.read_only_flag;
/* test logical view as needed */
select * from XYZ_SCHEMAS_MV#;
/* regenerate materialized view implementation */
exec ad_zd_mview.upgrade('APPS', 'XYZ_SCHEMAS_MV')
/* test materialized view as needed */
select * from XYZ_SCHEMAS_MV;
During an online patching cycle, out-of-date MV regeneration happens automatically during the cutover phase. But when working in the run edition of a development database, you will need to execute MV regeneration yourself when you are ready using the AD_ZD_MVIEW.UPGRADE procedure.
Extract the MV definition.
For all instances on R12.AD.C.Delta.8 and higher, use the following command. Enter the password when prompted. Alternatively, you could pass the password on the command line but this method might be insecure::
perl xdfgen.pl XYZ_SCHEMAS_MV
For all instances on R12.AD.C.Delta.7:
perl xdfgen.pl / XYZ_SCHEMAS_MV
For single node database instances on R12.AD.C.Delta.6 and lower:
perl xdfgen.pl /@ XYZ_SCHEMAS_MV
For RAC instances on R12.AD.C.Delta.6 and lower:
perl xdfgen.pl /@ XYZ_SCHEMAS_MV
Create the patch.
Patch files:
fnd/patch/115/sql/xyz_schema_types.sql
fnd/patch/115/xdf/xyz_schemas_mv.xdf
Manual apply phase actions for the file system:
cp fnd/patch/115/sql/* $FND_TOP/patch/115/sql
cp fnd/patch/115/xdf/* $FND_TOP/patch/115/xdf
Manual apply phase actions for the database for instances on R12.AD.C.Delta.8 and higher. Enter the password when prompted:
sqlplus @$FND_TOP/patch/115/sql/xyz_schema_types
xdfcmp.pl $FND_TOP/patch/115/xdf/xyz_schemas_mv.xdf
Manual apply phase actions for the database for instances on R12.AD.C.Delta.7 and lower:
sqlplus @$FND_TOP/patch/115/sql/xyz_schema_types
xdfcmp.pl