Call odi Mappig through PL/SQl Procedure - plsql

enter image description hereI have an anonymous block mentione below , i want to replace the execute immediate statement with the odi scenarion .
Any way of doing it with odi procedure. If i can use any odi api or odi utilities command to replace it.
i.e:
OdiStartScen "-SCEN_NAME=LD_T_RD_ACCOUNT_POC" "-SCEN_VERSION=001"
"-CONTEXT=GLOBAL" "-LOG_LEVEL=6" "-AGENT_CODE=OracleDIAgent1"
"-SYNC_MODE=1";
DECLARE
VAR VARCHAR2(2000);
VAR2 DATE;
BEGIN
BEGIN
Select XYZ INTO VAR
From DUMMY
Where ID= 2; end;
BEGIN
l_exec_sql:= 'INSERT INTO DUMMY VALUES('1')';
IF VAR LIKE 'XY%' THEN
execute immediate(l_exec_sql); --Replace it with odi scenario
ELSE
IF FUNCTION_F(VAR) THEN
execute immediate(l_exec_sql); --Replace it with odi scenario
END IF;
END IF;
END;

Regarding your anonymous block, you should rewrite it like this:
Create a new ODI package;
Create new variable named VAR (or how you like it), inside the var, put what you need, pairing with the proper logical schema;
open the newly create ODI Package, drag-and-drop the variable and choose the Refresh Variable Type (see below picture);
after drag-and-drop variable, choose it again and drag-and-drop, this time choosing the type Evaluate variable, and the write your first condition (see picture below);
then drag and drop what ODI scenario do you need;
You can "play" in many more ways with the odi package variables. For example, you can create a variable that will return YES if the first condition is meet and NO if second one is meet. Your variable will execute an sql statement and will return a value (only one row, one column) and then you will evaluate it and choose what scenario to execute.
Hope that it was useful
EDIT 1:
You can call an ODI Scenario from ODI Procedure, but the techonology should be ODI Tools, for the task that will call the scenario.
For your example you can do like this:
* inside your plsql block, where you have "--Replace it with odi scenario", place this substitution variables : ""; on the second variable evaluate, place "" etc;
* in the same procedure, make another task and write something like this:
<$
if (var.equals("call secenario 1") {
$>
OdiStartScen "-SCEN_NAME=NAMEOFSCENARIO" "-SCEN_VERSION=001"
<$
}
$>
This new task should have Techonology: ODI Tools.
You can't call the scenario in the same task that will run the plsql procedure, because the PLSQL procedure will need Technology Oracle and the calling of scenario will need ODI Tools.
EDIT 2:
To see the value in operator, go to your ODI Procedure, and please check the next option for each of your task. Save an regenerate the scenario (if you have a scenario):
EDIT 3:
Where to see the code in Operator:
Double click the session > choose the task you want to see> expand it> double click > Code

Related

I am trying to save the result of show con_name to a variable in ORACLE PL/SQL SQLPLUS

I want to write something like this:
exec SHOW CON_NAME into :=connection_name
but this doesnt work.
I know I can do this but I want to know for future reference if there is any way to do this for show
EXEC SELECT SYS_CONTEXT('USERENV','CON_NAME') into :connection_name from DUAL;
exec is just a wrapper for an anonymous block, so
exec SHOW CON_NAME into :=connection_name
is the same as
begin SHOW CON_NAME into :=connection_name end
Even with other issues fixed, show is a SQL*Plus client command, and doesn't mean anything inside a SQL or PL/SQL context.
You could do:
exec :connection_name := SYS_CONTEXT('USERENV','CON_NAME');
to avoid the context switch of selecting from dual within the PL/SQL.
Looking at the statement log in SQL Developer, show con_name is doing something similar, with a checkone bind variable it uses internally; though it also puts it through a local PL/SQL variable and trims that to 30 chars.
You could also use column ... new_value ... and query from dual, without using PL/SQL, and then use a substitution variable to refer to the value later instead of a bind variable:
column con_name new_value connection_name
select SYS_CONTEXT('USERENV','CON_NAME') as con_name from dual;
-- then later...
select '&connection_name' from dual;
Not sure how useful that would be though. Depends what you want to use it for I suppose.

Save result of plsql script in Kettle variable

What I want to do is storing the result of a PLSQL Script in a variable of a Kettle Transformation.
The script is located in a table input step and basically creates a select statement for me and puts it in a varchar variable of that PLSQL Script.
DECLARE
Statement VARCHAR(2000);
BEGIN
-- Here happens some stuff
Statement := 'select * from Foo';
END;
I just can´t figure out how I can map the variable Statement to one that exists in the Kettle Transformation.
Any ideas?
After a couple days I was able to solve this.
What I haven´t realized when I wrote the question was that a mere PLSQL Script doesn´t return anything.
The solution is actually very simple:
Create a new Transformation in Spoon.
Create a PLSQL Function (which has a return value of course).
Inside the new Transformation create a step "Table Input" and there you can call the function like this:
select myFunction('$someParameter') AS Statement FROM dual
If you want to provide some parameters for the function like I did make sure to check "replace variables in script" in the Table Input Step.
Connect that Step with a "Set Variables" Step ("Copy Rows to Result" works as well) and in my case I added the field Statement to the step with a new Variable that is valid in the parent job.

Need to get data from a table using database link where database name is dynamic

I am working on a system where I need to create a view.I have two databases
1.CDR_DB
2.EMS_DB
I want to create the view on the EMS_DB using table from CDR_DB. This I am trying to do via dblink.
The dblink is created at the runtime, i.e. DB Name is decided at the time user installs the database, based on the dbname dblink is decided.
My issue is I am trying to create a query like below to create a view from a table which name is decided at run time. Please see below query :
select count(*)
from (SELECT CONCAT('cdr_log#', alias) db_name
FROM ems_dbs a,
cdr_manager b
WHERE a.db_type = 'CDR'
and a.ems_db_id = b.cdr_db_id
and b.op_state = 4 ) db_name;
In this query cdr_log#"db_name" is the runtime table name(db_name get's created at runtime).
When I'm trying to run above query, I'm not getting the desired result. The result of the above query is '1'.
When running only the sub-query from the above query :
SELECT CONCAT('cdr_log#', alias) db_name
FROM ems_dbs a,
cdr_manager b
WHERE a.db_type = 'CDR'
and a.ems_db_id = b.cdr_db_id
and b.op_state = 4;
i'm getting the desired result, i.e. cdr_log#cdrdb01
but when i'm trying to run the full query, getting result as '1'.
Also, when i'm trying to run as
select count(*) from cdr_log#cdrdb01;
I'm getting the result as '24' which is correct.
Expected Result is that I should get the same output similar to the query :
select count(*) from cdr_log#cdrdb01;
---24
But the desired result is coming as '1' using the full query mentioned initially.
Please let me know a way to solve the above problem. I found a way to do it via a procedure, but i'm not sure how can I invoke this procedure.
Can this be done as part of sub query as I have used above?
You're not going to be able to create a view that will dynamically reference an object over a database link unless you do something like create a pipelined table function that builds the SQL dynamically.
If the database link is created and named dynamically at installation time, it would probably make the most sense to create any objects that depend on the database link (such as the view) at installation time too. Dynamic SQL tends to be much harder to write, maintain, and debug than static SQL so it would make sense to minimize the amount of dynamic SQL you need. If you can dynamically create the view at installation time, that's likely the easiest option. Even better than directly referencing the remote object in the view, particularly if there are multiple objects that need to reference the remote object, would probably be to have the view reference a synonym and create the synonym at install time. Something like
create synonym cdr_log_remote
for cdr#<<dblink name>>
create or replace view view_name
as
select *
from cdr_log_remote;
If you don't want to create the synonym/ view at installation time, you'd need to use dynamic SQL to reference the remote object. You can't use dynamic SQL as the SELECT statement in a view so you'd need to do something like have a view reference a pipelined table function that invokes dynamic SQL to call the remote object. That's a fair amount of work but it would look something like this
-- Define an object that has the same set of columns as the remote object
create type typ_cdr_log as object (
col1 number,
col2 varchar2(100)
);
create type tbl_cdr_log as table of typ_cdr_log;
create or replace function getAllCDRLog
return tbl_cdr_log
pipelined
is
l_rows typ_cdr_log;
l_sql varchar(1000);
l_dblink_name varchar(100);
begin
SELECT alias db_name
INTO l_dblink_name
FROM ems_dbs a,
cdr_manager b
WHERE a.db_type = 'CDR'
and a.ems_db_id = b.cdr_db_id
and b.op_state = 4;
l_sql := 'SELECT col1, col2 FROM cdr_log#' || l_dblink_name;
execute immediate l_sql
bulk collect into l_rows;
for i in 1 .. l_rows.count
loop
pipe row( l_rows(i) );
end loop;
return;
end;
create or replace view view_name
as
select *
from table( getAllCDRLog );
Note that this will not be a particularly efficient way to structure things if there are a large number of rows in the remote table since it reads all the rows into memory before starting to return them back to the caller. There are plenty of ways to make the pipelined table function more efficient but they'll tend to make the code more complicated.

PL/SQL parser to identify the operation on table

I am writing a PL/SQL parser to identify the operations(Select,Insert,Delete) performed on the Table when I run Procedure, Function or Package.
GOAL:I Goal of this tool is to identify which all the tables will be affected by running the procedure,Fun to prepare with better test case.
Any better ideas or tool will really help a lot.
INPUT:
some SQL file with procedure
or proc file.
OUTPUT required is:
SELECT from: First_table, secondTable
-> In procedure XYZ --This is if the procedure is calling one more procedure
INSERT into: SomeTable
INSERT into: SomeDiffTable
-> END of procedure XYZ --End of one more procedure.
DELETE from: xyzTable
INSERT into: OnemoreTable
My requirement is When I am parsing porc1 if it calls another proc2. I have to go inside that proc2 to find out what all the operation is performed in that and come back to proc1 and continue.:
For this I have to store the all procedure some where and while parsing I have to check each token(word with space) in the tempStorage to find out if it is procedure or not.
As my logic's takes lot of time. Can any body suggest better logic to achieve my GOAL.
There's also the possiblity of triggers being involved. That adds an additional layer of complexity.
I'd say you're better off mining DBA_DEPENDENCIES with a recursive query to determine impact analysis in the abstract; it won't capture dynamic SQL, but nothing will 100% of the time. In your case, proc1 depends on proc2, and proc2 depends on whatever it depends on, and so forth. It won't tell you the nature of the dependency - INSERT, UPDATE, DELETE, SELECT - but it's a beginning.
If you're really interested in determining the actual impact of a single-variable-value run of a procedure, implement it in a non-production system, and then turn auditing on your system up to 11:
begin
for i in (select owner, object_type, object_name from dba_objects
where owner in ([list of application schemas]
and object_type in ('TABLE', 'PACKAGE', 'PROCEDURE', 'FUNCTION', 'VIEW')
loop
execute immediate 'AUDIT ALL ON ' || i.owner || '.' || i.object_type ||
' BY SESSION';
end loop;
end;
/
Run your test, and see what objects got touched as a result of the exectution by mining the audit trail. It's not bulletproof, as it only audits objects that got touched by that execution, but it does tell you how they got touched.

Easiest method to test an Oracle Stored Procedure

I'm working on an ASP.NET project with an Oracle Database. We are using TOAD to add/manage the stored procedures -- and in general I like TOAD and Oracle. The one thing I've found frustrating is finding a simple way to test an Oracle Stored Proc, such as SQL Server's "exec [SP_NAME] Param1, Param2, ParamN" syntax.
All of our stored procedures output Ref Cursors. Here is an example of a Stored Proc:
CREATE OR REPLACE PROCEDURE APP_DB1.GET_JOB
(
p_JOB_ID IN JOB.JOB_ID%type,
outCursor OUT MYGEN.sqlcur
)
IS
BEGIN
OPEN outCursor FOR
SELECT *
FROM JOB
WHERE JOB_ID = p_JOB_ID;
END GET_JOB;
/
Any suggestions?
You just need a script that calls your stored procedure and has a bind variable for the ref cursor output to display it in TOAD's grid in the Editor window.
DECLARE
type result_set is ref cursor;
BEGIN
APP_DB1.GET_JOB(1, :result_set);
END;
When you then run this TOAD will prompt you to 'bind' :result_set, just select ref cursor from the list of types and then the result will display in the grid. The trick is to think of yourself as a 'client' calling your stored procedure and you need your own ref cursor to store the result.
If you just looking for a way to invoke the SP, then the Oracle way is:
begin
sp_name(....);
end;
I don't use Toad, but you should be able to put this into a SQL window and execute it.
In sqplus you can use the syntax
SQL>var rc refcursor
SQL>exec APP_DB1.GET_JOB(the job id you want to query, :rc)
SQL>print rc
That should do it. The first line defines a bind variable. You could also define a variable for the job id, or just type it in.
TOAD shows the result in a grid just fine with sample script from Russel. Run as script.
variable P_CUR refcursor;
exec PACK.GETEXECUTION ( '9f363e49-88c1-4295-b61e-60812d620d7e', '6', :P_CUR );
print P_CUR;
Thanks!
The idea is just to bind the outCursor variable to a cursor when toad prompts you for the variable type. Just pass the other variables the usual way. Like in the example below.
BEGIN
APP_DB1.GET_JOB(1, :v_outCursor);
END;
Run it and a dialogue box will prompt you to bind the :outCursor variable as shown in the following image.
Toad will then display the result in the result grid.

Resources