How to pass a dynamic list to ESQL Passthru query in IIB - ibm-integration-bus

I need to pass a dynamic list of parameters to SQL query in IIB. Please help me with any code snippets for this. Please note that we dont have privileges to create a Stored Procedure at DB end. So we need to pass the list of parameters to SQL query directly from IIB.
Scenario:
SET A= InputRoot.XMLNSC.Field1;
SET B= InputRoot.XMLNSC.Field2;
The number of above fields may vary dynamically.
SET query = select * from table where values in (?)
SET OutputRoot.XMLNSC.Result[] =Passthru (query To Database.DB) values (list)

Below is pseudocode. Assuming that you have a array of [LIST OF VALUES]. Try it out.
DECLARE PARM_1 CHAR '';
DECLARE QUERY CHAR;
FOR CURR AS {LIST OF VALUES} DO
SET PARM_1 = Write code to get list of values in the format => 'A','B','C'
END FOR;
--Comment: PARM_1 value now should be 'A','B','C'
--Comment : Below forming the query string and then use EVAL
SET QUERY = 'SELECT * FROM TABLE WHERE VALUE IN (' || PARM_1 || ')';
SET Environment.RESULT[] = EVAL(QUERY);

Related

Pl/SQL query a view in function

I have the function below
CREATE OR REPLACE FUNCTION BUTCE_REPORT_Fun (birim_id IN VARCHAR2)
RETURN sys_refcursor
IS
retval sys_refcursor;
BEGIN
OPEN retval FOR
select *
from ifsapp.butce_gerceklesme
WHERE budget_year = '2018'
AND USER_GROUP = birim_id ;
RETURN retval;
END BUTCE_REPORT_Fun;
and am trying to execute the function this way
SELECT * from table(IFSAPP.BUTCE_REPORT_FUN('3008'))
the line above generates this exception
ora-22905 cannot access rows from a non-nested table item
to keep in mind that ifsapp.butce_gerceklesme is a view (which I do not think that it matters).
So how I can solve this. any help is appreciated.
Actually, am trying to create a function that returns rows from the view above according to the parameters provided. so if I can achieve that in another way that would be better.
Ref Cursors are for use in program calls: they map to JDBC or ODBC ResultSet classes. They can't be used as an input to a table() call. Besides, there is no value in calling your function in SQL because you can simply execute the embedded query in SQL.
the main table is huge and the inner query assigned to USER_GROUP is selected every time
So maybe what you want is subquery factoring AKA the WITH clause?
with ug as (
select con2.CODE_PART_VALUE
from IFSAPP.ACCOUNTING_ATTRIBUTE_CON2 con2
where COMPANY = 'XYZ'
and ATTRIBUTE = 'ABC'
and CODE_PART = 'J'
and con2.ATTRIBUTE_VALUE=407
AND rownum = 1
)
select *
from ifsapp.butce_gerceklesme t
join ug on t.USER_GROUP = ug.CODE_PART_VALUE
WHERE t.budget_year = '2018'
Tuning queries on StackOverflow is a mug's game, because there are so many things which might be responsible for sub-optimal performance. But as a rule of thumb you should try to tune the whole query. Encapsulating a part of it in PL/SQL is unlikely to improve response times, and indeed may degrade them.

Update Oracle table using functions

I have the below queries and would like to update the corresponding data in the table that the queries return. Is it possible to utilize an update statement with an Oracle function? If so, how?
select *
from A
where translate(transnbr, '_0123456789', '_') is not null ;
select *
from A
where regexp_like(transnbr, '/*-+.') ;
Both queries return records as expected.
Would something along the lines the below work?
update a
set transnbr = translate(transnbr, '_0123456789', '_') ;
update a
set transnbr = regexp_like(transnbr, '/*-+.') ;
Thanks for any replies

How to replicate in LINQ a SQL query that uses Coalesce to pivot rows into a single column

How can I achieve this functionality from SQL in LINQ?
Here I am getting 3 SP Number to one Contract ID:
DECLARE #Names VARCHAR(8000)
SELECT #Names = COALESCE( #Names + ', ', '') + us.SP_NBR
FROM CAATS_ADMIN.CONTRACT_SP us
WHERE US.CNTRCT_ID='1000038'
You can use the LINQ aggregate function. You will need to retrieve the data in a SELECT to a list of strings through whatever data access mechanism you are using then you use the Aggregate like this:
List<string> source = GetMyData();
var b = source.Aggregate ("",
(current, s)=> string.Concat(current, string.Format("{0},", s)) );
This applies the string concatenation to every item in the sequence to build a single string.

PHP 5 oci_execute(): ORA-01008: not all variables bound

I am encountering this errir when attempting to do a merge:
PHP Warning: oci_execute(): ORA-01008: not all variables bound
I've made sure that all values that I have in the query are bound using the oci_bind_by_name() function, and that the data is valid.
Here is my code:
//Sample values just to test
$col1val = 'test1';
$col2val = 'test2';
$col3val = 'test3';
$col4val = 'test4';
$sql = "merge into tablespace.tb1 c using (select :col1val from dual) cd
on (c.col1 = cd.col1)
when not matched then
insert (c.col2, c.col1, c.col3, c.col4)
values (:col2val, :col1val, :col3val, :col4val)";
oci_bind_by_name($stid, ":col1val", $col1val);
oci_bind_by_name($stid, ":col2val", $col2val);
oci_bind_by_name($stid, ":col3val", $col3val);
oci_bind_by_name($stid, ":col4val", $col4val);
$stid = oci_parse($conn, $sql);
$result = oci_execute($stid);
oci_free_statement($stid);
I am using PHP 5 and Oracle 10g.
Any ideas?
The problem was that oci_bind_by_name() was being called before oci_parse(). oci_parse() needs to be called first.
I don't know how works "oci_bind_by_name", but I know that an EXECUTE IMMEDIATE statement under oracle will need a bind variable for each instance of the value you want to affect, for example, if you are using twice VAL1, you will still have to use 2 bind variables :1 AND :2, you can't use :1 twice.
So in your example, since ":col1val" is used twice, I would suggest you try to use a ":col5val" instead. Also, try to bind in the order of appearance of the variables in the script.
That's for my contribution :-) Keep us posted.
rgds.
your statemt is wrong, you needed an alias for the value in cd
merge into tablespace.tb1 c using (select :col1val col1 from dual) cd
on (c.col1 = cd.col1)
when not matched then
insert (c.col2, c.col1, c.col3, c.col4)
values (:col2val, :col1val, :col3val, :col4val)";

How to loop in sql?

I dont want to use the "loop" related keyword, how can I implement loop with basic sql command in oracle ?
I have two table :
A:
ID, Color
B,
ID, AID, Type
I want to loop all records in B, and if ID = AID, then set the A.Color = B.Type
Thanks in advance !
Looping is, by definition, a procedural construct.
SQL is declarative: tell the database what you want done, not how to do it.
If you're absolutely convinced that you need to program such a thing, then write it in PL/SQL, Oracle's procedural language.
Bu I'm sure that it's possible to do what you want in SQL using an UPDATE with a WHERE clause.
Something like this (corrected per NullUserException):
UPDATE A SET A.Color = (SELECT B.Type FROM B WHERE A.ID = B.AID)
An alternate method:
MERGE INTO a
USING b
ON (b.aid = a.id)
WHEN MATCHED THEN UPDATE SET a.color = b.type;
You could just do:
UPDATE tablea a
SET a.color = (SELECT b.type
FROM tableb b
WHERE b.aid = a.id)
See this SQL script.
To do that you will have to write a stored procedure using PL/SQL. Here is the oracle page with some info and papers on the topic.
As others pointed out, you can probably solve your problem with a normal DML statement, without any looping involved. But to give you some basics on how to accomplish what you asked for in PL/SQL, here's an example...
DECLARE
CURSOR c IS
SELECT id, aid, type FROM b;
statement VARCHAR2(200);
BEGIN
FOR iterator IN c LOOP
IF iterator.id = iterator.aid THEN
statement := 'UPDATE a SET color = ' || iterator.type || 'WHERE id = ' || iterator.id;
EXECUTE IMMEDIATE statement;
END IF;
END LOOP;
END;
This anonymous PL/SQL block will iterate through each record in table b, and if b.id = b.aid, it will update table a and set a.color = b.type where a.id = b.id.
This seems to be what you were asking for. It's not exactly an efficient way to go about doing things, since you're firing off one DML statement per row in table b that has b.id=b.aid. But I wanted more to give this as a syntax example. This is just one way to iterate through a cursor by the way; you can also explicitly open cursors and fetch records, but it's easier this way if you don't need to do anything but iterate over the entire result set.

Resources