Passing comma seperated parameter values through Oracle SOAP request - oracle

I running a BI Publisher report through SOAP request. the BI Publisher data model contain the following condition :
WHERE PERIOD_NAME IN ( :P_PERIOD_NAME )
when i pass single period like "Jan-21" it works fine but then when i pass "Jan-21, Feb-21" it fails.
how to pass comma separated values ?

You are passing in a single string (that happens to contain commas) and not a comma-separated list of multiple values so your query is effectively:
WHERE period_name IN ( 'Jan-21, Feb-21' )
Instead, surround both the delimited list and the list item in delimiters (so that you do not get a partial match) and then match on the substring:
WHERE ', ' || :P_PERIOD_NAME || ', ' LIKE '%, ' || period_name || ', %'
db<>fiddle here

Let try this query
SELECT *
FROM TABLE1
WHERE 1=1
AND PERIOD_NAME IN (
select regexp_substr('Jan-21,Feb-21','[^,]+', 1, level) as period from dual
connect by regexp_substr('Jan-21,Feb-21', '[^,]+', 1, level) is not null
);

Related

In Oracle execution time for finding a data inside comma seperated column taking too long

I am trying to find out if the list of data is in comma separated column. I have a code select * from my_table where (regexp_substr ( listcolumn, '[^,]+', 1, level ) in ('a','d')) connect by level <= regexp_count(listcolumn, ',') + 1; and table with a lot data. The problem is it works for small data table but it is taking too much time to execute for a lot a table with a lot of data. I am not expert in database. so can you please help to how to resolve this problem. Thank you in advance.
Don't split the string, look for a sub-string match (with the surrounding delimiters so that you match entire terms):
SELECT *
FROM my_table
WHERE ',' || listcolumn || ',' LIKE '%,' || 'a' || ',%'
OR ',' || listcolumn || ',' LIKE '%,' || 'd' || ',%';

Can you Insert a Carriage Return within a listagg function that is also concatenating different elements?

I am currently attempting to aggregate a list of concatenated values. However, I was wondering if it was possible to use a carriage return function within the listagg so that each concatenated value would be returned onto a new line. Does anyone have any experience with this? Thank you!
Here is a portion of my code: (Please note that this is also taking place inside a view join)
(select (listagg ((z.event_name || ' - ' || z.event_date), '; ') within group
(order by z.event_name))
from
a_visit_event z
where
z.subject_no = av.subject_no
and
z.visit_date = av.visit_date) event_name,
Just add chr(13)
i.e.
listagg ((z.event_name || ' - ' || z.event_date), '; '||chr(13))

How to add new line separator into data for oracle

I'm working on displaying data from oracle.
is there a way to make the following data inside the table:
example :
'1.somedata, 2.somedata, 3.somedata, 4.somedata, 5.somedata'
to display like:
example:
'1. somedata
2. somedata
3. somedata
4. somedata
5. somedata'
on the interface?
do i add new line separator directly into the data?
or do i separator them into new line when i query it?
or is there any other simple way?
Thanks.
There are so many ways to do this, here is one if you are selecting from a column:
SELECT REPLACE ('1.somedata, 2.somedata, 3.somedata, 4.somedata, 5.somedata', ',', CHR (13) || CHR (10)) AS split
FROM DUAL;
1.somedata
2.somedata
3.somedata
4.somedata
5.somedata
I personally would use the listagg function and use '' as the delimiter.
SELECT LISTAGG(last_name, ' ')
WITHIN GROUP (ORDER BY hire_date, last_name) "Emp_list",
MIN(hire_date) "Earliest"
FROM employees
WHERE department_id = 30;
Remember that Apex is generating a web page, which means the end result is HTML. Apex, however, will also sometimes escape special HTML characters for you, like < and &. Since you're viewing a table, I assume the source of your data is a query and your "somedata" field is a single column. Try this:
SELECT REPLACE( somedata_column, ',', '<br />' )
FROM mytable
You don't say what version of Apex. In Apex 4.x, the column would need to be set to a Standard Report Column, which would stop Apex from the <br> elements. I forget what the column type is in Apex 5.x.
Check below sample query which converts coma separated list data into rows
SELECT substr( '1.AL,2.AL,3.AL,4.AL,5.AL,6.AL,',
( case when rownum = 1 then 1
else instr( '1.AL,2.AL,3.AL,4.AL,5.AL,6.AL,', ',', 1, rownum - 1 ) + 1
end ),
instr( substr( '1.AL,2.AL,3.AL,4.AL,5.AL,6.AL,',
( case when rownum = 1 then 1
else instr( '1.AL,2.AL,3.AL,4.AL,5.AL,6.AL,', ',', 1, rownum - 1 ) + 1
end )
), ',' ) - 1
) as data
FROM dual
CONNECT BY LEVEL <= length( '1.AL,2.AL,3.AL,4.AL,5.AL,6.AL,' ) - length ( replace('1.AL,2.AL,3.AL,4.AL,5.AL,6.AL,', ',') )
Hope this will help you!

Cannot insert empty string in oracle table

i am trying to insert data into one of my table.
insert into t_transaction_query_log
(log_id,
posting_id,
fee_id,
fee_status,
fee_type,
pay_mode,
accounting_date,
policy_id,
money_id,
finish_time,
source_type,
fee_amount,
cr_seg,
dr_seg,
product_id' || v_insert_str_cr_seg ||
v_insert_str_dr_seg || ')
select s_transaction_query_log__lg_id.nextval,
tg.je_posting_id,
tg.fee_id,
tg.fee_status,
tg.fee_type,
60,
tg.accounting_date,
tg.policy_id,
tg.currency_id,
trunc(sysdate,
''dd''),
2,
tg.fee_amount,' ||v_str_cr_seg
|| ',' || v_str_dr_seg || ',
tg.product_id' || v_insert_str_cr_seg ||
v_insert_str_dr_seg || '
from t_ri_fee_gl tg
where tg.posted = ''Y''
i have declared v_str_cr_seg,v_str_dr_seg as empty strings i.e v_str_dr_seg varchar(50)='';
before executing this query i am able to append some values to these two strings
but in case there is no change in these strings from the declaration
i am getting the computed query as
insert into t_transaction_query_log
(log_id,
posting_id,
fee_id,
fee_status,
fee_type,
pay_mode,
accounting_date,
policy_id,
money_id,
finish_time,
source_type,
fee_amount,
cr_seg,
dr_seg,
product_id)
select s_transaction_query_log__lg_id.nextval,
tg.je_posting_id,
tg.fee_id,
tg.fee_status,
tg.fee_type,
60,
tg.accounting_date,
tg.policy_id,
tg.currency_id,
trunc(sysdate,
'dd'),
2,
tg.fee_amount, , ,
tg.product_id
from t_ri_fee_gl tg
where tg.posted = 'Y'
which in turn results in missing expression error.
i have tried using nvl function as
nvl(v_str_cr_seg, '') and `nvl(v_str_cr_seg, null)`
but still i am getting the same error
how can i insert even though v_str_cr_seg and v_str_dr_seg are unchanged
i.e empty strings ''
Ora DB:
empty string = null
enter link description here
Note:
Oracle Database currently treats a character value with a length of zero as null. However, this may not continue to be true in future releases, and Oracle recommends that you do not treat empty strings the same as nulls.
If this is an insert Statement in the middle of a PL/SQL Routine, then you would not string concatenate. It would rather look like this
tg.fee_amount, v_str_cr_seg, v_str_dr_seg
But something from your question tells me that you are composing a string that you want to execute immediate.
In this case you have to make sure you are giving quotes:
tg.fee_amount,''' ||v_str_cr_seg
|| ''',''' || v_str_dr_seg || ''',
tg.product_id''' || v_insert_str_cr_seg ||
v_insert_str_dr_seg || '''
You need to escape the single quote (') with two quotes in a row ('')
But if your strings already come with quotes around it unless null you may want to work with nvl this way
tg.fee_amount,' ||nvl(v_str_cr_seg,'''''')
|| ',' || nvl(v_str_dr_seg,'''''') || ',
Try using chr(0) instead of ''. Null character is a sign of the end of a string.

Sum Listagg in a query

I am trying to sum the values from the listagg query i made.
Expected result should be like this
SELECT LEGAL_ENTITY_ID, SUM(0 + 0 + 0 + 1) as Grandtotals
FROM V_VBA_DDCR_MAIN WHERE LEGAL_ENTITY_ID=6012346 AND ROWNUM=1
GROUP BY LEGAL_ENTITY_ID
| LEGAL_ENTITY_ID | GRANDTOTALS
1| 6012346 | 1
My listagg goes like this
SELECT LISTAGG(NVL2(FLDNM,0,1) , '+ ') WITHIN GROUP (ORDER BY FLDNM) FROM LE_MERGE_DDC_MAPPING
the purpose of this query is to count the number of null fields in a row. I created a table containing the list of fields that needs to be checked for null values.
Result :
fld1 + fld2 + fld3 + fld4
=
0 + 0 + 0 + 1
So I wrote my query like this:
SELECT LEGAL_ENTITY_ID, SUM(SELECT LISTAGG(NVL2(FLDNM,0,1) , '+ ') WITHIN GROUP
(ORDER BY FLDNM) FROM LE_MERGE_DDC_MAPPING) as Grandtotals
FROM V_VBA_DDCR_MAIN WHERE LEGAL_ENTITY_ID=6000132
GROUP BY LEGAL_ENTITY_ID
However, I am getting an error ORA-00936: missing expression.
I am not sure if Oracle allows you to do a sum of the listagg function.
Any help is appreciated.
Your SELECT LISTAGG(NVL2(FLDNM,0,1) , '+ ')... query will always get string result '0+ 0+ 0+ ...', unless you have rows in LE_MERGE_DDC_MAPPING which are null. That value is nothing to do with the V_VBA_DDCR_MAIN table. You could generate a string that contains the expressions:
SELECT LISTAGG('NVL2(' || FLDNM || ' ,0,1)' , '+ ') ...
But that would just leave you with a string containing 'NVL2(fld1 ,0,1)+ NVL2(fld2 ,0,1)+ ...'. You can't sum a string, and sum() can't evaluate a string as an expression. You would need to generate a dynamic SQL statement based on that string.
There is a way to do that with XML, which isn't entirely intuitive. You can use the dbms_xmlgen package to create an XML document (as a CLOB) which contains a node with the NVL2 result from your actual target table:
select dbms_xmlgen.getxml('select nvl2(' || fldnm || ',0,1) from v_vba_ddcr_main where legal_entity_id=6012346')
from le_merge_ddc_mapping map;
I won't show the generated XML here. You can then query that to get the individual values out:
select xmlquery('/ROWSET/ROW/*/text()'
passing xmltype(
dbms_xmlgen.getxml('select nvl2(' || fldnm || ',0,1) from v_vba_ddcr_main where Legal_Entity_Id=6012346')
)
returning content)
from le_merge_ddc_mapping;
And you can them sum those:
select sum(to_number(xmlquery('/ROWSET/ROW/*/text()'
passing xmltype(
dbms_xmlgen.getxml('select nvl2(' || fldnm || ',0,1) from v_vba_ddcr_main where legal_entity_id=6012346')
)
returning content))) as grandtotals
from le_merge_ddc_mapping;
You've suggested there is a link between the tables, to determine which fields are included, so you'd need to add that. And you've said there are duplicates, which you'd need to handle - preferably by eliminating them from your view, but with a subquery if necessary. This can be a starting point for you to develop from though.
Why use LISTAGG at all?
SELECT LEGAL_ENTITY_ID,
(
SELECT COUNT(1)
FROM LE_MERGE_DDC_MAPPING
WHERE FLDNM IS NULL
) as Grandtotals
FROM V_VBA_DDCR_MAIN
WHERE LEGAL_ENTITY_ID=6000132;
(Since you are filtering on a single LEGAL_ENTITY_ID you don't need the final GROUP BY)
Are you sure there shouldn't be some sort of join condition between the two tables?

Resources