Friday, November 30, 2007

Queuing / Messaging

Oracle ERP use of AQ (queuing) / Messaging to send data to, or receive data from, external applications using the ERP Hub (no direct or point-to-point messaging ).




  • Queue tables will be designed to maximize re-use and multiple inbound and outbound queues will reside in a single queue table.

  • Message data being published or subscribed by ERP via the Hub will be in XML format.


ERP Database


User Roles/Object Privileges: On the ERP instance, all queueing and messaging should be run under the APPS user and, as such, APPS requires and should already have the user role:

AQ_ADMINISTRATOR_ROLE

And the object privileges:
EXECUTE ON DBMS_AQ
EXECUTE ON DBMS_AQADM

Since the queue tables, indexes etc will reside under a custom schema (see next heading), that schema will also require this role and object privileges.

Queue Tables: ERP customizations using queues should create the queue tables and indexes in the customization’s schema. For example, interfaces to/from external applications will use the INFX schema.
Queue tables should be designed to maximize use. Multiple inbound and outbound queues for manipulating messages on various types of business data such as customer, order, invoice, product, purchase order, etc. can utilize a single queue table. The important factors to consider in deciding whether to implement a new queue table depend on the personality assigned to the queue table at creation (will the messages have a single or multiple consumers, will the messages be sorted in ascending or descending order and by what attributes, what is the object type of the message’s payload).

For ERP interfaces using the ERP Hub, a single queue table will be defined as follows in the INFX schema. This queue table uses a custom object type to define the payload as an XML-formatted message in a CLOB, it sets the sorting order by priority and timestamp, and sets it for multiple consumer consumption as required by the Hub.. Interface developers should use this queue table for both inbound and outbound messages that fit within the properties of this queue table. Following are examples: These database objects do not yet exist in ERP:

Create the Queue Table, Inbound and Outbound Queues as the INFX user:
ASC_OAI_STD_MSG_TYPE (custom object type)
ASC_OAI_QTAB (custom queue table)
ASC_OAI_INQ (inbound queue)
ASC_OAI_OUTQ (outbound queue)

Here is how this queue table is created:

Custom Object Type:

Sign onto SQL*Plus as the custom user (ie, INFX/INFX) and create the custom object type for the message payload, if this object type does not already exist (script NOAImsgtyp.sql):

CREATE OR REPLACE
TYPE ASC_OAI_STD_MSG_TYPE AS OBJECT(
APPLICATION VARCHAR2(30),
PUBLISH_DATE DATE,
OBJECT_NAME VARCHAR2(100),
EVENT_NAME VARCHAR2(100),
CORRELATION_ID VARCHAR2(100),
XML_DATA CLOB)
/

GRANT EXECUTE ON ASC_OAI_STD_MSG_TYPE TO public
/

Queue Table and In/Out Queues:


Then execute the following NOAIqcreat.sql script that will create the ASC_OAI_QTAB table, then define the ASC_OAI_INQ and ASC_OAI_OUTQ queues. This script checks whether the queues already exists and execute the correct DBMS_AQADM procedures:




REM============================================================
REM
REM Create New Queue Table
REM
REM============================================================
declare
queue_table_exists exception;
pragma EXCEPTION_INIT(queue_table_exists, -24001);
begin

dbms_output.put_line('===================================');
dbms_output.put_line('Creating OAI Queue Tables ');
dbms_output.put_line('===================================');

begin
dbms_aqadm.create_queue_table
(
queue_table => 'ASC_OAI_QTAB',
queue_payload_type => 'ASC_OAI_STD_MSG_TYPE',
sort_list => 'PRIORITY,ENQ_TIME',
comment => 'OAI application queue',
multiple_consumers => TRUE,
compatible => '8.1'
);

exception
when queue_table_exists then
null;
when others then
dbms_output.put_line('Oracle Server Error = 'to_char(sqlcode));
dbms_output.put_line('Oracle Server Message = 'sqlerrm);
raise_application_error(-20000, 'Oracle Error Mkr1= '
to_char(sqlcode)' - 'sqlerrm);
end;
end;
/

REM====================================================================
REM
REM Create New Queue
REM
REM====================================================================

declare
queue_exists exception;
pragma EXCEPTION_INIT(queue_exists, -24006);
BEGIN

dbms_output.put_line('=================================');
dbms_output.put_line('Creating all Queues');
dbms_output.put_line('=================================');

begin
dbms_aqadm.create_queue
(
queue_name => 'ASC_OAI_INQ',
queue_table => 'ASC_OAI_QTAB',
comment => 'OAI Application In Queue',
retention_time => 60*60*24 /* ONE day in seconds */
);
dbms_aqadm.create_queue
(
queue_name => 'ASC_OAI_OUTQ',
queue_table => 'ASC_OAI_QTAB',
comment => 'OAI Application Out queue',
retention_time => 60*60*24 /* ONE day in seconds */
);

exception
when queue_exists then
null;
when others then
dbms_output.put_line('Oracle Server Error = 'to_char(sqlcode));
dbms_output.put_line('Oracle Server Message = 'sqlerrm);
raise_application_error(-20000, 'Oracle Error Mkr4= '
to_char(sqlcode)' - 'sqlerrm);
end;
END;
/

Start the Queues as the APPS user:
See script NOAIqstrt.sql

REM===================================================================
REM
REM Start Queue
REM
REM===================================================================

declare
begin

dbms_output.put_line('============================');
dbms_output.put_line('Starting all Queues ');
dbms_output.put_line('============================');

dbms_aqadm.start_queue(queue_name => 'ASC_OAI_INQ');
dbms_aqadm.start_queue(queue_name => 'ASC_OAI_OUTQ');

exception
when others then
dbms_output.put_line('Oracle Server Error = 'to_char(sqlcode));
dbms_output.put_line('Oracle Server Message = 'sqlerrm);
raise_application_error(-20000, 'Oracle Error Mkr7= '
to_char(sqlcode)' - 'sqlerrm);
end;
/
commit;

Views/Triggers/Packages/Functions : All views, triggers, stored procedures, packages and functions for ERP AQ Messaging to the Hub should be prefixed ASC_OAI_ , be suffixed as described in the Database Objects document and be created in the APPS schema.
Source Files/SQL Scripts

All source files, SQL scripts etc related to ERP AQ Messaging to the Hub should be named with the prefix NOAI followed by meaningful string and extension as documented in the Database Objects document. See the Interface Standards document for more information on file naming standards.

Defining Metadata and the Hub Repository :

  • Get the ERP adapter updated and registered
  • Generate the XML DTDs
  • iStudio tool to map Common Views of the data and set up subscribers/publishers
  • Identify the ways to monitor / test messages routed through the Hub and processes executing on the Hub


Processing on the Hub : If interface design drives the moving of processing from the ERP instance to the HUB instance, additional guidelines should be developed. There is no APPS schema on the hub. This is an Oracle 8i database with 9iAS for message management and is where the messaging repository resides. The apps are not installed so there is no Concurrent Manager, etc. However, there is the Business Events System and Workflow 2.6 available to developers on this instance.

External Applications : Any database objects that ERP developers may help to create on an external application’s database in moving to AQ Messaging will follow that application’s development standards wherever possible.

Database Objects

Schemas
Names
ASCX Default schema; for all general ASC customizations that are not IE, interface, transition or migration related.
IEXX Invoice Engine schema
INFX Schema for tables used to interface outside of this environment on a permanent basis.
TRNX Tables needed to contain data during the transition between an organization's previous environment and this environment. These are not permanent interface tables, but they will be needed for a time longer than the initial data migration.
MIGX Tables needed for migration of an organization into the environment. These objects may be dropped and then re-created for each new organization.
TXWI Taxware International schema.

Tablespaces

Each schema should have a _DATA and an _INDEX tablespace.

Object Creation
1- Tables/Indexes/Sequences: All custom tables, indexes, and sequences should be created in a custom schema.
2. Views/Triggers/Packages/Functions: All views, triggers, stored procedures, packages and functions should be placed in the APPS schema.

Naming Standards: Database object names should be:

a. Unique (relative to applications at the site);
b. End user oriented;
c. Unambiguous;
d. Consistent;
e. Brief.

Prefix:
. All Custom objects should have a name that begins ASC_.
. Logical Grouping should be two to four characters that represent the project, application short name or other area that is responsible for maintaining it the customization.

Some Logical Grouping suggestions:
ONT Order Management
ARX Accounts Receivable
IE Invoice Engine
CIF CIF
SHR Objects shared by all customizations

Tables:
Naming Standard
a. All tables must be prefixed with ASC_.
b. Should be Plural

Good Example: ASC_ONT_SOFTWARE_ATTRIBUTES
Bad Example: ASC_SOFTWARE
c. Translation Tables should have a suffix of _TL. A translation table is a table used to maintain data that can be different based on language.

Schema
Tables should be created in a custom schema – see schema section above.

Table Structures

All parameters should be fully specified in all DDL statements, even if the default value is to be accepted.

Rather than do: create table SAMPLE (COL1 VARCHAR2 20);

Do: create table ASC_ONT_SOFTWARE
(COL1 varchar2(20) not null,
COL2 date)
pctfree 10
pctused 70
initrans 1
maxtrans 99
tablespace ASCX_DATA
storage (initial 128K
next 128K
minextents 1
maxextents 550
pctincrease 0)
nocache;

The following chart should be used as a guideline for establishing extent sizes:
Please consult a dba on large table.

Table Size - Initial Extents - Next Extents
Small - 128K - 128K
Medium - 512K - 512K
Large - 1M - 1M
X-Large - 2M - 2M

Every table should include the following columns to support the Who processing feature:

CREATION_DATE default sysdate (Not Null, DATE)
CREATED_BY (Not Null, NUMBER)
LAST_UPDATE_LOGIN (Null Allowed, NUMBER)
LAST_UPDATE_DATE default sysdate (Not Null, DATE)
LAST_UPDATED_BY (Not Null, NUMBER)

The only exception is when a table is created for the sole purpose of maintaining temporary data.

Order table columns as follows:

a. Primary key column(s)(major to minor);
b. CREATION_DATE;
c. CREATED_BY;
d. LAST_UPDATE_LOGIN;
e. LAST_UPDATE_DATE;
f. LAST_UPDATED_BY;
g. Mandatory (NOT NULL) columns;
h. Key flexfield columns if any (SEGMENT1 mandatory, others optional);
i. Optional columns;
j. Descriptive Flexfield context column, if any;
k. Descriptive Flexfield segment columns, if any.
l. ORG_ID, if data must be separated by operating unit

Quickcodes/Lookups: Two custom tables have been created under the ASCX schema to maintain all lookup codes and their values.
ASC_SHR_LOOKUP_TYPES
ASC_SHR_LOOKUP_VALUES

Do not create additional lookup tables.

Views
Naming Standards

a. Start with ASC_.

b. Suffix with _V or _TLV for views that retrieve data from a translation table(s) for a specific language.

c. Are end user oriented:

d. Are brief while avoiding unnecessary abbreviation:

Schema: Views should be created under the apps schema.


Columns in Table and Views

Columns should have names that:

a. Omit a table prefix:

Good: ACTIVE_DATE
Bad: LPV_ACTIVE_DATE (in GL_PLAN_VERSIONS table)

b. Include a table prefix only when part of a primary key (i.e. an “ID”, “NAME”, “NUM” column) to allow foreign key columns to have the same name:

Good: PLAN_VERSION_ID
TIME_PERIOD_NAME
REQUISITION_LINE_NUM

Bad: ID
NAME
NUM

c. Are singular:

Good: FIRST_TIME_PERIOD
Bad: FIRST_TIME_PERIODS

d. Are brief (up to 15 characters), while avoiding unnecessary abbreviations:

Good: DESCRIPTION
Bad: DESC

Make a foreign key column name match the corresponding primary key column name, e.g.;

Good: TIME_PERIOD_NAME (to refer to column TIME_PERIOD_NAME in the table GL_TIME_PERIODS).

Bad: TP_NAME, PERIOD_NAME or TIME_PERIOD.

Column Suffixes
The following column types should be named as follows:

Date Columns: should have a meaningful name followed by "_DATE"
Flags: should have a descriptive name followed by "_FLAG"
Sequences: should have a descriptive name followed by "_ID"
Lookup code: should match the value of the lookup_type which should end with _CODE
For example: (ACTIVE_DATE, MERGE_ID, MOVE_FLAG, SYSTEM_CODE)

Multi Org column: should be org_id

Language for translation: should be LANGUAGE NOT NULL VARCHAR2(4)



Sequences:
Naming Standard
a. Start with ASC_
b. Ends with _S
c. Contain a description or table name, if applicable
Sequence ASC_DDDDDD_S DDDDDD = Description/Table Name if
used to generate a primary key for a table.

S = Sequence
Schema
Sequences should be created in a custom schema, not the apps schema.


Data Types
Naming Standard
a. Start with ASC_
b. Ends with _TYPE
Schema
Data types should be created in a custom schema, not the apps schema. They will be included in the grant_synonym script so the apps schema will become aware of them.

Triggers
Naming Standard
a. For a custom table; start with table or view name.
b. For a standard Oracle table, prefix with ASC_ and followed by the table or view name
c. Ends with type of trigger

Database Trigger ASC_TABLE_XYZN TABLE = Base table or view name
X: B = Before A = After O =Other;instead of
Y: S = Statement R = Row
Z: I = Insert U = Update
D = Delete
N: One digit trigger id (if more
than 1 trigger of a type exist)

Schema
Triggers should be created in the apps schema.

Stored Packages
Naming Standard
a. Starts with ASC_
b. Ends with _PKG

Query Function Packages ASC_XXX_QUERY_PKG
A query function package is a package that contains only query functions. This naming standard is consistent with the applications query function packages.

Stored Package ASC_XXX_DDDDDD_PKG
DDDDDD = Description
PKG = Package (up to 32 char)

Schema
Procedure packages should be created in the apps schema.

Stored Procedures
Naming Standard
a. Starts with ASC_
b. Ends with _PROC

Procedures that are created within a package should have a descriptive name.

Procedures that are stand alone (not created within a package) should be named as follows:
Stored Procedure ASC_XXXX_DDDDDD_PROC
XXXX – logical grouping
DDDDDD = Description
PROC = signifies procedure
Schema
Stand alone procedures should be created in the apps schema.

Stored Functions
Naming Standard
a. Starts with ASC_
b. Ends with _FCN

Functions that are created within a package should be named descriptive.

Functions that are stand alone (not created within a package) should be named as follows:
Stored Function ASC_XXXX_DDDDDD_FCN
DDDDDD = Description
FCN = signifies function

Query functions – Needs Validated in 11i
When you are creating query functions (i.e. for a view), you must add the following line in the package specification after defining the function
pragma RESTRICT_REFERENCES (SOC_LOOKUP_VALUE, WNDS, WNPS);

A query function is a function that does not perform an insert, update, or delete.
This statement tells the Oracle parser that the function does not change any database values. This statement is important because you cannot use a function in a select statement that alters data within the database (i.e., it cannot update, insert or delete records or alter database objects).
Schema
Stand alone functions should be created in the apps schema.

Indexes
Naming Standard
Indexes _PK, _N1, _U1, etc (no need to put the 'C' if the name begins with ASC)

a. For a custom table should start with tablename
b. For a standard Oracle table; should start with ASC_ and followed by table name.
c. Ends with type of index PK=primary key
OR
U=unique N=Non-unique and sequential number


Index ASC_DDDDDD_Tn DDDDDD = Description

PK = primary key index
OR
T: U= Unique N= Non-Unique
n = sequential number

Indexes should have names that:

a. Reflect the name of the table they index:

Good: ASC_GL_TIME_PERIODS_U1
Bad: TP_INDEX

b. Show they are a primary key index via a suffix of “_PK”

Good: ASC_GL_TIME_PERIODS_PK
Bad: GL_TIME_PERIODS

c. Show they are unique via a suffix of “_Un” (where “n” is a number from 1 to 9):

Good: ASC_GL_TIME_PERIODS_U1
Bad: GL_TIME_PERIODS

d. Show that they are non-unique via a suffix of “_Nn” (where “n” is a number from 1 to 9):

Good: ASC_GL_TIME_PERIODS_N1
Bad: GL_TIME_PERIODS
Schema
Indexes should be created in a custom schema, not the apps schema.

APPL_TOP Stuff

. Under the standard APPL_TOP there will be an asc_custom directory. All custom files will be placed somewhere under this directory.

. Under asc_custom there will be the following directories:

ascx
iexx
infx
trnx
migx
txwi

. The standard structure under each of these subdirectories will be:

bin
forms
help
install
log
mesg
out
reports
sql

Data objects

Data objects and their schemas:
  • Objects owned by base schema-
    - Tables
    - Indexes
    - Sequences
  • Objects owned by APPS schema
    - Views
    - Packages
    - Procedures
    - Functions
    - Triggers
  • Custom schemas for ASC might be:
    - ASCX: General ASC Customizations
    - INFX: Permanent interfaces
    - TRNX: Interfaces that are not permanent
    - MIGX: Migration of an organization’s data into ERP - recreated for each org
    - IEXX: Invoice Engine


Grants and synonyms to APPS

• Done by Oracle for tables and sequences in standard schemas
• Done by ASC for tables and sequences in custom schemas
(currently in FARGO environment you can execute the script
$ASCX_TOP/install/db/grant_syn.sql as apps to create all
necessary grants/synonyms for prompted schema)
• Must be redone if table or sequence is re-created


Database Object Naming

  • Tables ASC_XXX_TABLENAME
  • Indexes ASC_TABLENAME_T# (T: U-Unique N- Non-unique )
  • Sequences ASC_XXX_SEQUENCENAME_S
  • Views ASC_XXX_VIEWNAME_V
  • Packages ASC_XXX_PACKAGENAME_PKG
  • Procedures ASC_XXX_PROCEDURENAME_PROC
  • Functions ASC_XXX_FUNCTIONNAME_FCN
  • Triggers ASC_TABLENAME_XYZN
    (X: B=Before A=After O= Other -Instead Of
    Y: S=Statement R= Row
    Z: I=Insert U=Update D=Delete
    N: Digit if more than 1 trigger for a type exists)
    NOTE: XXX is a 2-4 character logical grouping

Truncating tables as APPS: The truncate command does not utilize synonyms. Must either:
•Be in same schema as table
•Hard code schema name
•Use a function or procedure, e.g. ASC_APPS_TRUNCATE_PROC('INFX_MY_TABLE');

Modifying Oracle Code

The steps that you should follow when modifying standard Oracle code for a stored procedure, package, or function. For non-database related files, follow the standards as much as possible.

Naming Convention

The file that contains the modified code should be named oracle_. to easily identify modified Oracle code/objects.

For example, if you need to modify a function in a procedure maintained in the file OEXULINB.pls, the file name would be something like oracle_OEXULINB.sql. If it is a package being modified, the file should contain both the package spec and package body.

Comments

Include at least one comment line that contains “ASC” within the first 20 lines of the object. For example:

/* $Header: INVTISVB.pls 115.44.11580.6 2003/10/20 04:00:52 rmurari ship $*/
/* Customized by ASC for ERP 3.0 */
/*===========================================================================+
Copyright (c) 2000 Oracle Corporation
Redwood Shores, California, USA
All rights reserved.

Repository
1. The original unmodified standard Oracle file should be added to the repository under /vob/erp/asc_custom/orig. This should help when an Oracle patch is applied.
2. The modified file name should be placed in the same directory as other customizations.

Exception Log: Update the exception log, if applicable.

Common Database Objects

A common object is an object that could be used by multiple groups. It could be a generic function, such as one to retrieve the ID for a user. It could be a table that multiple groups could query to get the same information (i.e. serial numbers).

You do not need to wait to see if multiple groups need your object before deciding that it could be a common one. If you feel there is potential for your object to be used by other groups, go ahead and create it as a common one.

Naming Standards:

  • The object should be named according to the naming standards for that object.
  • If an object was created as something specific to one group and then later decided that it could be a common one, the name of the object should be changed if the existing coding changes could easily be updated. If it is difficult to update the existing code with a new name for an object, then leave the object name as it is.

Schemas:

  • Common objects should be created under the ASCX schema (if table or sequence) or under the APPS schema (if function, view, or procedure).

    Note: There may be exceptions for objects created for a single group, then converted to a common one.

Modifications to Common Objects:

If a common object needs to be updated, an email should be sent to the development team with the details of the desired change. If there are no objections to the change, the requestor can modify the common object and update any pertinent information in the list below. If there are objections, requestor can set up a meeting with opposing parties to see if a common solution can be reached or requestor should create a similar, but private object with exact needs.

Tuesday, November 27, 2007

R11i - Coding Standards

ALIAS: If you are writing code that joins to more than two tables, it is recommended that aliases be used. The use of aliases resolves the problem of ambiguity, when the same column name resides in more than one table. The alias should be used on each table in the where clause, and on each table’s corresponding columns in the select statement. The alias name should be something short, but meaningful. For example, the alias for the table mtl_system_items_b could be msi. The alias for oe_order_headers_all could be ooh.

Who Columns:

Which user: Default values for “CREATED_BY and LAST_UDPATED_BY columns should not utilize -1 or 2.

If you have a custom program that performs DML, you need to set the created by and last_updated_by columns in the table. If possible, use the actual user who is performing the database change. If it is a concurrent program, you can use the username DISTBATCH, CONVERSION (for conversion programs), or PURGEUSER (for purge programs).

Date columns: CREATION_DATE and LAST_UPDATE_DATE should default to sysdate. Date columns need to be on all tables.


Database Object Script Naming Standards:

These scripts should contain all of the statements necessary to create custom tables, indexes, sequences, functions, procedures, packages, triggers, and views. Scripts will be created to handle standard grants and synonyms (those between the custom schema and APPS). Special grants and synonym scripts may be necessary.

  • Table, Index, and Sequence Scripts - The scripts that contain statements for tables, indexes, or sequences must have something in the name that makes it obvious that they will need to be run under a custom schema. They can contain "tbl" for tables, "idx" for indexes, "seq" for sequences, or "tis" if the script creates more than one of these objects. Do not include drop statements in these scripts if this is the initial release of the tables. Alter scripts should be separate from create scripts. The name of the alter script should be very similar to initial table creation script. For example, if the original script to create the table was arxcurr_tbls.sql, then an alter for one of the tables should be put in a script called arxcurr_tblsXXXX.sql (where XXXX is the release number). The original script should also be updated to include the additional column(s).
  • All modules are installed as if part of a separate product. A directory structure is created under $APPL_TOP.
  • Customizations on standard Oracle tables – The only type of customizations allowed on standard Oracle tables are for the creation of indexes and triggers. However, during some upgrades we are asked to drop or disable these objects. Assuming that triggers follow the naming standards, the installation should be able to identify custom triggers on standard Oracle table and simply disable/enable them. However, since indexes must be dropped, we will need to have custom indexes on standard Oracle tables placed in separate scripts so that the scripts can be re-run to put the objects back after the upgrade. These scripts should be placed in $ASCX_TOP/install/db. The naming of the index scripts should be ora__description_idx.sql where XXX is the Oracle schema that contains the index.
  • Create or Replace – Any objects that allow "create or replace" should use this. The name of the object should follow immediately on the same line and be in upper case. On the line below should be the version number of the object. For example,

    create or replace procedure ASC_APPS_TRUNCATE_PROC
    /* Version: ERP 1.0 */
  • Script Header and Footer – So that the installation works properly, each script should have the following information at the beginning and ending.

    set echo on
    set feedback on

    /* Name: lookup_tbl.sql */
    /* User: Run this script as ASCX */
    .
    .
    blah, blah, blah
    .
    .
    /* end of lookup_tbl.sql */

    exit
  • Spool Commands – Spooling to a log file is not necessary. The installation process will generate a log file of its own. The log for a script will be placed in the $XXXX_TOP/install/db/logs directory.
  • Connect Commands – Do not add the connect command to the script since it will require that you hard code the user name and password. The automated installation process will determine the actual user name and password to use.

Code Alignment Indentation: All programs need to indent for each level within a program. Proper alignment will ensure readability of code when nested IF’s are required.

Comments and In-Line Documentation

All programs should be thoroughly commented. The purpose should be to impart as much information about the program as possible. Therefore, all SQL*Forms triggers should be commented, the structure of the queries in a SQL*Reportwriter program should be described in the comments, etc. The specific recommendations will be described in later sections. However, the most important comment in any program will be the Program History Log (PHL). The PHL will contain the following program details:

a. Copyright information;
b. Project identification;
c. File name;
d. File type (for example, Stored Procedure, PL/SQL, SQL, Unix Shell);
e. Program Short Name;
f. Program Full Name;
g. Description;
h. Called from (indicate the calling program, if any);
i. Executes (indicate any programs executed by, if any);
j. Parameters:
k. Version Control format = Header: 99.99.99.99.99 (where 99.99.99.99.99 follows the standards for the Version Number)
l. Change History;
i. Date of Change;
ii. Author of Change;
iii. Change Reference;
iv. Comments / Description of Change;
m. Any information required for the Configuration Management software.

The PHL will be created by the original author of the program and then updated by subsequent authors.

Example 1:
/*************************************************************************/
/* Copyright 2001 by ASC Corporation */
/* All Rights Reserved */
/* */
/* Project: ERP 1.0 */
/* File: INTAPLRP.SQL */
/* File Type: Stored Procedure */
/* Program Short Name: N/A */
/* Program Full Name: N/A */
/* */
/* Description: ie_add_lookup_stp */
/* This procedure adds a lookup entry to a table. */
/* */
/* Called from: lookups.sql */
/* Executes: N/A */
/* */
/* Parameters: N/A */
/* */
/* Header: 01.00.00.00.00 */
/* Date of Author of Change Comments / Description */
/* Change Change Ref. of Change */
/* --------- ----------- ------ ------------------------------ */
/* 30-OCT-01 J.Public N/A Initial Release 1.0 */
/* */
/* */
/*************************************************************************/

Example 2:
/*************************************************************************/
/* Copyright 2001 by ASC Corporation */
/* All Rights Reserved */
/* */
/* Project: ERP 1.0 */
/* File: GL000000.frm */
/* File Type: GL form */
/* Program Short Name: GL000 */
/* Program Full Name: REPORT ACCOUNTING INFORMATION */
/* */
/* Description: This dummy report is used to show the */
/* development standards. */
/* */
/* Called from: N/A */
/* Executes: N/A */
/* */
/* Parameters: N/A */
/* */
/* Header: 01.00.00.00.00 */
/* Date of Author of Change Comments /Description */
/* Change Change Ref. of Change */
/* --------- ----------- ------ ------------------------------ */
/* 30-OCT-01 J.Public N/A Initial Release 1.0 */
/* */
/* */
/*************************************************************************/

This standard PHL will ensure that the team will be able to keep an accurate record of any changes to any of the customized programs developed on the project.

In addition to adding header level comments add comments within the body of any code that explain constants, any anything that would occur out of the order. Comments need to explain the business reasons or process for code. Make sure that comments are not just a verbal translation of the statement.

Document constants:
IF (i = 1) THEN – Business Case 1 to trigger customer set-up
V := ‘First Case’;
ELSIF (i=2) THEN – Business Case 2 to trigger interface
V := ‘Second Case’;
ELSE
V := ‘Default’; -- Default Case all others numbers 3-9
END IF;

Unix Shell Script Standards:

Header Standards: Each script will include a header section at the beginning of each file.

Example:
#!/bin/sh
#*************************************************************************
#* Copyright 2001 by ASC Corporation *
#* All Rights Reserved *
#* *
#* $Header: pocjfprn.sh (VERSION 1.0.0.0.0) *
#* *
#* Project: ERP 1.0 (RFC 115347) *
#* File: pocjfprn.sh *
#* File Type: Unix Shell Script *
#* Program Short Name: N/A *
#* Program Full Name: N/A *
#* *
#* Description: Driver to print or fax PO's to JetForm. *
#* *
#* Called from: Oracle submit requests form *
#* Executes: N/A *
#* *
#* Parameters: -j - optional, flag to indicate *
#* PO's should be faxed and *
#* not printed *
#* -d - optional, debug flag *
#* -p printer_name - user selected printer *
#* -p printer_name - user selected printer *
#* -f filename - PO's to be printed or faxed *
#* *
#* Version Date of Author of Change Comments / Description *
#* Number Change Change Ref. of Change *
#* ------- --------- ----------- ------ ----------------------------- *
#* 1.0 30-OCT-01 A. Smits N/A Initial Release 1.0 *
#* *
#* *
#*************************************************************************

Version Control Standards: All Unix Shell Script files will be version controlled. When making changes to script files at the header section of the file is an area to keep COS/FMS version control.

Example:
#* $Header: pocjfprn.sh (VERSION 1.0.0.0.0) 110.1 97/09/17 13:10:24 pejohnso ship $
This line describes the
$Header: file name - (ASC's Version Control) – [Oracle's Version Control - Date/Time Created – Author]
Note: “Oracle’s Version Control – Date/Time Created - Author” is option and should be include only if the original script was released by Oracle.

As the script file needs changing the internal development version number will increment by 1.
Example:
Initial Version put in CME 1.0.0.0.0
Fix during CIT 1.0.0.0.1
--------Phase 1 released -------
Bug fixed in Patch 3 1.0.0.3.0
Fix during Patch 3 CIT 1.0.0.3.1
Fix during Patch 3 SAT 1.0.0.3.2
-------Patch 3 released----------
New Stuff added for Phase 2 1.1.0.0.0
More new stuff for Phase 2 1.1.0.0.1
Fix during SAT 1.1.0.0.2

Version Control:

All programs will be placed under Software Configuration Management (SCM) control. Subsequent changes to a program will require the version number to be changed. The breakdown of a version is as follow:

Version number 99.99.99.99.99. Where
_ Internal development version number
_ Patch number
_ Maintenance release number **
Point release number
Major release number

** Since there will be fairly regularly scheduled point releases, there will be no need for maintenance releases on a quarterly basis.

The internal development version number starts with 0 with any new release. See examples below:

Example 1:
The first version for a ERP piece of code would be 1.0.0.0.0

Example 2:
If the code needs to be changed during testing (before released for production), the developer should change the internal development version to 1 and increment the number by 1 for each subsequent change. During CIT a problem is detected. The code is checked out of the repository and changes are made. The version should be updated to ERP 1.0.0.0.1. If an another change is required, the version should be 1.0.0.0.2

Example 3:
If the code needs changed for ERP 1.1, the version should be changed to 1.1.0.0.0

Example Summary:
Initial version put in ACME 1.0.0.0.0
Fix during CIT 1.0.0.0.1
------Phase 1 released ---------------
Bug fixed in patch 3 1.0.0.3.0
Fix during patch 3 CIT 1.0.0.3.1
Fix during patch 3 SAT 1.0.0.3.2
------Patch 3 released ----------------
New stuff added for Phase 2 1.1.0.0.0
More new stuff for Phase 2 1.1.0.0.1
Fix during SAT 1.1.0.0.2


Each type of file (i.e. pl*sql, form, library, database script) has a specific standard on how and where to include the version number.

Invoker vs. Define Rights:
A definer-rights procedure (or package or function) executes with its owner's privileges. Roles are disabled in a definer-rights procedure and in any procedure invoke directly or indirectly by a definer-rights procedure.

An invoker-rights procedure (or package or function) executes with all of the invoker's privileges, including currently enabled roles. If the invoker-rights procedure was invoked directly or indirectly by a definer-rights procedure, no roles are enabled.

The Oracle database default is definer-rights. However, there is an administrator function within the apps to set these rights for you if you have not explicitly done so. When this runs, it will set it to invoker-rights for any package, procedure and function it finds under the apps schema. Yes, Oracle will change custom objects. So to prevent this from happening, it is best to be explicit.

If your package is owned by APPS and it has definer-rights, no matter who you are when executing the package, it will run with the privileges of APPS. (This is how it had functioned before 8i.) However, if your package is owned by APPS and has invoker-rights, it will run with the privileges of who you are when you are executing it. For example, if you log into sqlplus using IEXX and run an APPS package with invoker-rights, you will have the privileges of IEXX, not APPS.

Here is an example. The words in red are what you need to add if you want it to run with definers rights. If you are adding this to a package, you only need to do this to the package header (not the body).

create or replace procedure ASC_APPS_TRUNCATE_PROC
/* Version: ERP 1.0 */
(v_syn_name IN VARCHAR2,
v_reuse_flag IN VARCHAR2 DEFAULT 'NO')
authid definer IS
BEGIN
DECLARE

blah, blah, blah

END ASC_APPS_TRUNCATE_PROC;

Performance Coding:
1) When necessary, include in your code a call to asc_appl_info_pkg and set the name of your code.
For example,
ASC_APPL_INFO_PKG.SET_MODULE('ASC_WSH_DEL_ASSIGNMENTS_ARIU1','');
When the performance team is reviewing code that is being executed, they can tell what package/trigger/function is being executed.

2) Also, when the code is complete you should reset the value to null. This will prevent your trigger/package/function displaying as database object that is executing after your code.

For example, in your exception handler, before a return statement
ASC_APPL_INFO_PKG.RESET();

OM Debug Statements: If you want to include OM debug statements in your code following the steps below:
Declare
X_DEBUG_FILE varchar2(100);
begin
oe_msg_pub.initialize;
oe_debug_pub.initialize;
X_DEBUG_FILE := OE_DEBUG_PUB.Set_Debug_Mode('FILE');
oe_debug_pub.SetDebugLevel(5);
Oe_debug_pub.add('ASC: put your debug message here');

For subsequent debug statements, you only need to include the
Oe_debug_pub.add('ASC: debug message here');

SQL Error Debugging Standards : For debugging purposes add a location variable to all code (nLoc_Num NUMBER). Assign a unique number to each SQL statement so in the event of a failure a support analyst can track back to the specific SQL statement that failed. The location variable, procedure/function name needs to be displayed along with the SQL error message and code in the exception handler. This process will help a support analyst debug the code in the event that it fails. Wherever possible if an error message can be placed to an error table this is helpful for support. Display counts as needed to verify inserts.

Listed below are examples of exception handlers with error processing:

CREATE OR REPLACE PROCEDURE asc_ar_event_revenue_proc ()
nLoc_num NUMBER;
vCode VARCHAR2(32) := 'ASC_AR_EVENT_REVENUE_PROC';
vErrBuf VARCAHR2(2000);
vPlace VARCHAR2(10);
nCount NUMBER;

BEGIN
nLoc_num := 10;
SELECT ‘10’ -- First Select Statement in Code
INTO vPlace
FROM DUAL;


nLoc_num := 20;
SELECT ‘20’ -- Second Select Statement in Code
INTO vPlace
FROM DUAL;

nLoc_num := 30;
SELECT ‘30’ -- Third Select Statement in Code
INTO vPlace
FROM DUAL;

nLoc_num := 40;
INSERT INTO ASC_TEMP
SELECT 10, 20, 30
FROM DUAL;

nCount := SQL%ROWCOUNT;
DBMS_OUTPUT.put_line (vCode ‘ Insert total: ‘ TO_CHAR (nCount));

EXCEPTION
WHEN OTHERS THEN
ROLLBACK;
pErrBuf := SUBSTRB(vCode ‘-‘ 'Loc: ' TO_CHAR(nLoc_num)
' Oracle Code-Message:' SQLCODE '-' SQLERRM, 1,2000);

INSERT INTO ASC_ERROR_TBL
(ID, RECORD_ID, MESSAGE, CREATED_BY, CREATION_DATE, PROGRAM, LOC)
VALUES
(ASC_ERROR_TBL _S.nextval, v_place, pErrBuf, '-1', SYSDATE, vCode, nLoc_num);

COMMIT;
raise_application_error(-20000, pErrBuf);

END;

Triggers cannot contain rollback so here is another example of code.

CREATE OR REPLACE TRIGGER ASC_TRIGGER_UI1
BEFORE
UPDATE
ON ASC.ASC_TABLE
REFERENCING OLD AS OLD NEW AS NEW
FOR EACH ROW
DECLARE
nLoc_num NUMBER;
vCode VARCHAR2(32) := ‘ASC_TRIGGER_UI1’;
vErrBuf VARCAHR2(2000);
vPlace VARCHAR2(10);
BEGIN
nLoc_num := 10;
SELECT ‘10’ -- First Select Statement in Code
INTO vPlace
FROM DUAL;


nLoc_num := 20;
SELECT ‘20’ -- Second Select Statement in Code
INTO vPlace
FROM DUAL;

SELECT ‘30’ -- Third Select Statement in Code
INTO vPlace
FROM DUAL;

EXCEPTION
WHEN OTHERS THEN
pErrBuf := SUBSTRB(vCode ‘-‘ 'Loc: ' TO_CHAR(nLoc_num)
' Oracle Code-Message:' SQLCODE '-' SQLERRM, 1,2000);

raise_application_error (-20000, vErrBuf);
END;