Tuesday, January 20, 2009

Informatica and Stored Procedures

Belated New Year Wishes to all.Hope the new year brings happiness to all.

Having relocated to a new place, it took sometime for me to settle...hence forth there will be a regular update in the blogs.

A. Described below is a scenario where the requirement is to have a stored procedure that returns a cursor as a source.

By and large PowerCenter does not support a stored procedure that returns a cursor as a source. The workaround for this is

1. The procedure that will load the data to a new table:

CREATE OR REPLACE procedure load (p_initial_date in date, p_final_Date in date) as

str_load varchar2 (500);
str_clean varchar2 (500);
begin
str_clean:= 'DELETE FROM EMP';
str_load:= 'INSERT INTO EMP select * from EMPLOYEE where DOJ between trunc

(p_initial_date) and trunc (p_final_Date) ';
execute immediate str_clean;
execute immediate str_load;
EXCEPTION
WHEN OTHERS
THEN
ROLLBACK;
end load;


2. Create the table that will receive the data from the procedure:

SQL> create table EMP as SELECT * from EMPLOYEE where 1 > 2;

3. Add a Store Procedure transformation to the PowerCenter mapping. This transformation will execute this new procedure called as LOAD on this example.

4. Set the run method to be Source Pre Load, to be executed before read the source table.

5. Import the EMP table as a Source Definition. This table will be populated by the new Store Procedure.

If the original store procedure is used by the customer application and you can't change the source code, you can create a new store procedure that call the original one (without inserting into a table), and execute the insert on the new table executing a loop on the returned cursor.

B. Given below is a situation where you wanted to pass a mapping variable to a stored procedure transformation (it can either be connected or unconnected).

Connected Stored Procedure

The parameters that are passed to a connected Stored Procedure have to be linked from another transformation.
Given below are the steps to pass mapping variable to a connected Stored Procedure transformation:

Create an Expression transformation.
Create an output port in the Expression transformation with the following expression:
$$mapping_variable

This sets the value of this output port to the mapping variable.

Link this output port to the Stored Procedure transformation.
Unconnected Stored Procedure

For unconnected Stored Procedure transformations you can use the mapping variable in the expression calling the stored procedure.
Follow the steps below to pass mapping variable to a unconnected Stored Procedure transformation:

Create an Expression transformation.
Create an output port in the Expression transformation with the following expression:
: SP.GET_NAME_FROM_ID ($$mapping_variable, PROC_RESULT)

In case if you are attempting to use a mapping variable to store the output value of the stored procedure, the session will fail with the below error.

"TE_7002 Transformation Parse Fatal Error; transformation stopped: invalid function reference. Failed to Initialize Server Transformation."

To resolve the issue replace the mapping variable with the PROC_RESULT system variable.

Example:

Incorrect, using a mapping variable:

:SP.PROCEDURE(FIELD1, $$mapping_variable)



Correct, using the PROC_RESULT system variable:

:SP.PROCEDURE(FIELD1,PROC_RESULT)

Or

:SP.PROCEDURE($$mapping_variable,PROC_RESULT)

The PROC_RESULT system variable assigns the stored procedure output to the port with this expression.

Thanks for reading.
Please do share your thoughts/comments.

2 comments:

Siri said...

I have something like SP_TRUNCATE_TABLE('local_schema',$$table_name)

The table exists in the schema, but I am getting an error of "Insufficient privileges or no table exists". This happens randomly. Can you please suggest, what is the ideal way to write it?
I have no output parameters here.

Thanks!

Jamie Beu said...

How do I use a stored procedure in the Pre SQL attribute of a target?
For example, I want to run a “truncate table” stored procedure (I don’t trust Informatica’s “truncate” check box) to truncate my target table.
Unfortunately, Informatica doesn’t use the SQL*Plus “EXECUTE” command, nor does it allow me to wrap the procedure in a BEGIN…END block.
Any ideas?