Issue with comma seperated varchar and Number field in oracle - oracle

i have written this stored procedure in Oracle:
CREATE OR REPLACE PROCEDURE TMS.SP_BOOKING_CANCEL_SMPL(P_BOOK_TERMINAL NUMBER,
P_BOOK_CODE NUMBER,
P_BOOK_NO VARCHAR2,
P_CANCELLATION_SEATS VARCHAR2,
P_CANCEL_QTY NUMBER,
P_CANCEL_AMOUNT NUMBER,
P_CANCEL_SEAT_QTY NUMBER,
P_SEAT_QTY NUMBER,
P_UNCANCELLED_ID VARCHAR2,
P_UNCANCELLED_QTY NUMBER,
P_CANCEL_TERMINAL NUMBER,
P_CANCEL_SITE NUMBER,
P_CANCEL_SEQ NUMBER,
P_CANCEL_TYPE CHAR,
P_USER_ID VARCHAR2,
P_SYNC CHAR,
P_CREATE_IP VARCHAR2,
P_CREATE_PC VARCHAR2)
IS
d_sql VARCHAR2(32767);
V_CANCEL_CODE NUMBER;
BEGIN
d_sql := 'UPDATE TMS_BOOKD SET BOOKD_CANCEL_YN = ''Y'', BOOKD_CANCEL_DATE = SYSDATE, BOOKD_CANCEL_USER = :UserId, BOOKD_GENDER = NULL
WHERE BOOKD_TERMINAL = :BookDTerminal AND BOOKD_CODE = :BookDCode AND BOOKD_SEAT in (:cancellationIds)';
EXECUTE IMMEDIATE d_sql
USING P_USER_ID, P_BOOK_TERMINAL, P_BOOK_CODE,P_CANCELLATION_SEATS ;
--;
IF P_CANCEL_SEAT_QTY = P_SEAT_QTY
THEN
d_sql := 'UPDATE TMS_BOOKM SET BOOKM_SET_SEATS = NULL, BOOKM_SET_QTY = NULL, BOOKM_SET_AMOUNT = NULL, BOOKM_CANCEL = 1 WHERE BOOKM_TERMINAL = :BookDTerminal
AND BOOKM_CODE = :BookM_Code AND BOOKM_BOOKNO = :BookM_No';
EXECUTE IMMEDIATE d_sql
USING P_BOOK_TERMINAL, P_BOOK_CODE, P_BOOK_NO;
ELSE
d_sql := 'UPDATE TMS_BOOKM SET BOOKM_SET_SEATS = :BOOKM_SET_SEATS, BOOKM_SET_QTY = :BOOK_SET_QTY, BOOKM_CANCEL = 1 WHERE BOOKM_TERMINAL = :BookDTerminal
AND BOOKM_CODE = :BookM_Code AND BOOKM_BOOKNO = :BookM_No';
EXECUTE IMMEDIATE d_sql
USING P_UNCANCELLED_ID, P_UNCANCELLED_QTY, P_BOOK_TERMINAL, P_BOOK_CODE, P_BOOK_NO;
END IF;
END;
/
i am executing this stored procedure with parameter 'P_CANCELLATION_SEATS ' with value: '10,12'
however it throws exceptions: Ora-01722(invalid number) in first query, the issue is most probably with the IN clause comparing Number type column value with string type value in my parameter.
can anyone tell me how can i resolve this issue?

There are few thing which you must keep in mind before running a Proc. First one is whether you need a DYNAMIC SQL . In your case Dynamic SQL is not at all needed. You can directly do it as shown in my code below. Secondly you already identified that you table column BOOKD_SEAT is a NUMBER coulmn and you are trying to compare with a String so its obvious it will through error. You need to pass these values as collection. See below:
You modified code :
--Create a type of Number to hold your input values
CREATE OR REPLACE TYPE var IS TABLE OF NUMBER;
/
CREATE OR REPLACE PROCEDURE TMS.SP_BOOKING_CANCEL_SMPL (
P_BOOK_TERMINAL NUMBER,
P_BOOK_CODE NUMBER,
P_BOOK_NO VARCHAR2,
P_CANCELLATION_SEATS var, -- Declare the input as type of NUMBER
P_CANCEL_QTY NUMBER,
P_CANCEL_AMOUNT NUMBER,
P_CANCEL_SEAT_QTY NUMBER,
P_SEAT_QTY NUMBER,
P_UNCANCELLED_ID VARCHAR2,
P_UNCANCELLED_QTY NUMBER,
P_CANCEL_TERMINAL NUMBER,
P_CANCEL_SITE NUMBER,
P_CANCEL_SEQ NUMBER,
P_CANCEL_TYPE CHAR,
P_USER_ID VARCHAR2,
P_SYNC CHAR,
P_CREATE_IP VARCHAR2,
P_CREATE_PC VARCHAR2)
IS
V_CANCEL_CODE NUMBER;
BEGIN
UPDATE TMS_BOOKD
SET BOOKD_CANCEL_YN = 'Y',
BOOKD_CANCEL_DATE = SYSDATE,
BOOKD_CANCEL_USER = P_USER_ID,
BOOKD_GENDER = NULL
WHERE BOOKD_TERMINAL = P_BOOK_TERMINAL
AND BOOKD_CODE = P_BOOK_CODE
AND BOOKD_SEAT IN (select column_value from table(P_CANCELLATION_SEATS) );
-- Note you can also use MEMBER of operator and change query as
--BOOKD_SEAT MEMBER OF P_CANCELLATION_SEATS
IF P_CANCEL_SEAT_QTY = P_SEAT_QTY
THEN
UPDATE TMS_BOOKM
SET BOOKM_SET_SEATS = NULL,
BOOKM_SET_QTY = NULL,
BOOKM_SET_AMOUNT = NULL,
BOOKM_CANCEL = 1
WHERE BOOKM_TERMINAL = P_BOOK_TERMINAL
AND BOOKM_CODE = P_BOOK_CODE
AND BOOKM_BOOKNO = P_BOOK_NO;
ELSE
UPDATE TMS_BOOKM
SET BOOKM_SET_SEATS = P_UNCANCELLED_ID,
BOOKM_SET_QTY = P_UNCANCELLED_QTY,
BOOKM_CANCEL = 1
WHERE BOOKM_TERMINAL = P_BOOK_TERMINAL
AND BOOKM_CODE = P_BOOK_CODE
AND BOOKM_BOOKNO = P_BOOK_NO;
END IF;
END;
/
Execution:
DECLARE
v_var var := var ();
BEGIN
v_var.EXTEND (2);
--Populate all the values which you want to evalued in IN calsue.
v_var (1) := 1;
v_var (2) := 2;
TMS.SP_BOOKING_CANCEL_SMPL (P_BOOK_TERMINAL => <give your value>
P_BOOK_CODE => <give your value>
P_BOOK_NO => <give your value>
--- pass all the value which you want to be evaluted in IN clause of your query
P_CANCELLATION_SEATS => v_var
P_CANCEL_QTY => <give your value>
P_CANCEL_AMOUNT => <give your value>
P_CANCEL_SEAT_QTY => <give your value>
P_SEAT_QTY => <give your value>
P_UNCANCELLED_ID => <give your value>
P_UNCANCELLED_QTY => <give your value>
P_CANCEL_TERMINAL => <give your value>
P_CANCEL_SITE => <give your value>
P_CANCEL_SEQ => <give your value>
P_CANCEL_TYPE => <give your value>
P_USER_ID => <give your value>
P_SYNC => <give your value>
P_CREATE_IP => <give your value>
P_CREATE_PC => <give your value> )
end;

The parameter P_CANCELLATION_SEAT is a list of comma separated values that you want to pass inside the IN clause, the way you are trying to achieve is technically wrong, you have to break the comma separated valued into list of values before using it in the IN clause.
d_sql := 'UPDATE TMS_BOOKD SET BOOKD_CANCEL_YN = ''Y'', BOOKD_CANCEL_DATE = SYSDATE, BOOKD_CANCEL_USER = :UserId, BOOKD_GENDER = NULL
WHERE BOOKD_TERMINAL = :BookDTerminal AND BOOKD_CODE = :BookDCode AND BOOKD_SEAT in (SELECT to_number(regexp_substr(vlist, ''[^,]+'', 1, LEVEL))
FROM (SELECT :cancellationIds AS vlist FROM dual)
CONNECT BY regexp_substr(vlist, ''[^,]+'', 1, LEVEL) IS NOT NULL)';
BTW, why are you using dynamic SQL? All your operations can be performed using simple SQL statements.

Related

Item Query From Table and Send It To Procedure

Note
I want to query page item name and send the corresponding items value into a procedure. I can get the item name but couldn't get the value of it. At first I use the following code:
begin
for j in (select item_name from UTLITMINF where service_id ='abc' ) loop
val := val || ':' || j.item_name; --items name
END LOOP;
/* exe := ' begin
dynamic_api_call(p_service => :ser,
p_par => :v_val, --items value to need to send
o_result_json => :v_l_response_text);
end; ';
execute immediate exe
using IN ser,
in val,
out l_response_text;*/
begin
dynamic_api_call(p_service => 'abc',
p_par => val, --items name from page queried from table and send its value to procedure
o_result_json => l_response_text);
end;
raise_application_error(-20001,l_response_text);
end;
In val parameter it contains P11_CUSTOMER. But the value of it did not pass through the procedure. How can I get the value of it? Suggest me if i need to improve my code.
You can use the V (short for value) and NV (short for numeric value) function for dynamic item names. Try something like this (you'll need to adjust on your end).
declare
l_response_text varchar2(255);
l_ser varchar2(255) := 'abc';
l_item_name varchar2(255);
begin
select item_name
into l_item_name
from UTLITMINF
where service_id = l_ser;
dynamic_api_call(
p_service => l_ser,
p_par => v(l_item_name),
o_result_json => l_response_text
);
end;
Try the dynamic sql like the below
begin
for j in (select item_name from UTLITMINF where service_id ='abc' ) loop
val := val || ':' || j.item_name; --items name
END LOOP;
exe := ' begin
dynamic_api_call(p_service => :ser,
p_par => :v_val, --items value to need to send
o_result_json => :v_l_response_text);
end ;';
execute immediate exe
using ser,
val,
OUT l_response_text;
raise_application_error(-20001,l_response_text);

Update: Function Error: PLS-00306: wrong number or types of arguments in call to 'get_bus_result_attribute'

I just think the problem of issue and change the function-to-function logic design. Then, the error as mentioned the function (get_result_attribute) - PLS-00306: wrong number or types of arguments in call to 'get_result_attribute'. May I know the function "get_result_attribute" problem in which part?
Coding for the bus station system.
FUNCTION get_bus_result_attribute (iv_result_name varchar2,
iv_result_key varchar2,
iv_result_attribute varchar2)
--define the parameter to get the "sql_result" script result
RETURN varchar2 IS
sql_result varchar2(500);
sql_return varchar2(500);
BEGIN
sql_result := 'SELECT ' || iv_result_attribute || '
FROM MyTable a,
MyTable b
WHERE a.bus_value_set_id = b.bus_value_set_id
AND b.bus_value_set_name = iv_result_name
AND a.enabled_flag = ''Y''
AND a.bus_value = iv_result_key
AND iv_result_name = get_bus_code (v_bus)
AND iv_result_key = get_bus_name(v_group)
AND iv_result_key = iv_result_attribute';
EXECUTE IMMEDIATE sql_result
INTO sql_return; --get the "sql_result" script result
return sql_return;
exception
when others then
return '';
end get_bus_result_attribute;
FUNCTION get_bus_code (v_bus varchar2)
RETURN VARCHAR2 IS
v_get_bus_code_result VARCHAR2(20) ;
BEGIN
SELECT busa.bus_code
INTO v_get_bus_code_result
FROM tbl_bus_code busa, tbl_bus_line busb
WHERE busa.bus_code_set_id = busb.bus_code_set_id
AND busb.bus_line_set_name = 'HK_BUS_CODE'
AND busa.enabled_flag = 'Y'
AND (busa.attribute4 = 'Y' OR busa.attribute5 = 'Y')
AND busa.BUS_VALUE = v_bus;
RETURN v_get_bus_code_result;
RETURN get_result_attribute('BUS_LINES', v_bus, 'attribute1'); /*BUS_GP*/
EXCEPTION
WHEN OTHERS THEN
RETURN '';
END get_bus_code;
FUNCTION get_bus_name(v_group VARCHAR2) --define the parameter and enter the value in the function 'get_bus_result_attribute'
RETURN VARCHAR2 IS
v_get_bus_div_result VARCHAR2(20) ;
BEGIN
SELECT DISTINCT CASE busa.bus_code --Bus code
WHEN '52' THEN '52X'
WHEN '58P' THEN '58'
WHEN 'K1' THEN 'K1C'
WHEN '40' THEN '40X'
WHEN '6' THEN '6X'
WHEN '7' THEN '7'
WHEN '58M' THEN '58'
ELSE ''
END bus_code --Bus code
INTO v_get_bus_div_result
FROM tbl_bus_code busa, tbl_bus_line busb
WHERE busa.bus_code_set_id = busb.bus_code_set_id
AND busb.bus_line_set_name = 'HK_BUS_LINES'
AND busa.enabled_flag = 'Y'
AND (busa.attribute4 = 'Y' OR busa.attribute5 = 'Y')
AND busa.bus_code NOT IN ('INACTIVE', 'XXX')
AND get_bus_code(busa.BUS_VALUE) = v_group
RETURN get_result_attribute('BUS_GROUP', v_group, 'attribute2');
--bus_group_dir
EXCEPTION
WHEN OTHERS THEN
RETURN '';
END get_bus_name;
FUNCTION BUS_DOC_TEXT (N_ID NUMBER, N_HEAD_ID NUMBER)
RETURN VARCHAR2 IS
v_bus_doc_text VARCHAR2(150);
BEGIN
SELECT 'BUS\'
|| get_bus_result_attribute(abc.attribute14)
|| '\'
|| abc.attribute14
|| '\'
|| abc.segment1
INTO v_bus_doc_text
FROM my_table_c abc
WHERE abc.ORG_ID = N_ID -- parameter
AND abc.bus_id = N_HEADER_ID; -- parameter
END;
RETURN v_bus_doc_text ;
END;
END;

Oracle function, how to pass parameters to cursor and use it

Here is one of oracle functions. There is a cursor called c_adv_course_credit which receives 2 parameters. These 2 parameters are using the where statement:
WHERE
-- year
cc.year = p_year AND
-- rela_pk
cc.sequence_number = p_sequence_number AND
cc.closed_ind = 'N';
When I run it in oracle sql developer:
SET SERVEROUTPUT ON
variable res varchar2(200);
EXECUTE :res := advp_test_cursor(2018, 92919);
select :res from dual;
The result text is always "not working"
Here is the full function (not working):
CREATE OR REPLACE Function SISD_OWNER.advp_test_cursor (
p_sequence_number IN NUMBER, -- rela_pk
p_year IN NUMBER -- year
)
RETURN VARCHAR2
IS
v_return_var VARCHAR2(300) := 'not working';
CURSOR c_adv_course_credit (
p_sequence_number IN NUMBER,
p_year IN NUMBER
)
IS
SELECT
cc.EXTERNAL_COURSE_CD
FROM
adv_course_credit cc
WHERE
cc.year = p_year AND
-- rela_pk
cc.sequence_number = p_sequence_number AND
cc.closed_ind = 'N';
BEGIN
FOR v_at_rec IN c_adv_course_credit(p_sequence_number, p_year) LOOP
v_return_var := v_at_rec.EXTERNAL_COURSE_CD;
DBMS_OUTPUT.PUT_LINE('?output = ' || v_return_var);
EXIT;
END LOOP;
RETURN v_return_var;
END;
If I change the cursor to use hard-coded numbers the function works and returns actual result.
WHERE
-- year
cc.year = 2018 AND
-- rela_pk
cc.sequence_number = 92919 AND
cc.closed_ind = 'N';
Your function is defined as (ignoring the data types):
advp_test_cursor(p_sequence_number, p_year)
but you're calling it as
advp_test_cursor(2018, 92919);
which has the arguments the wrong way round. You either need to flip them:
advp_test_cursor(92919, 2018);
or use named parameter notation:
advp_test_cursor(p_year=>2018, p_sequence_number=>92919)
or indeed combine both:
advp_test_cursor(p_sequence_number=>92919, p_year=>2018)
You do not need to use cursors:
CREATE OR REPLACE Function SISD_OWNER.advp_test_cursor (
p_sequence_number IN adv_course_credit.sequence_number%TYPE,
p_year IN adv_course_credit.year%TYPE
) RETURN adv_course_credit.EXTERNAL_COURSE_CD%TYPE
IS
v_return_var adv_course_credit.EXTERNAL_COURSE_CD%TYPE;
BEGIN
SELECT EXTERNAL_COURSE_CD
INTO v_return_var
FROM adv_course_credit
WHERE year = p_year
AND sequence_number = p_sequence_number
AND closed_ind = 'N';
DBMS_OUTPUT.PUT_LINE('?output = ' || v_return_var);
RETURN v_return_var;
EXCEPTION
WHEN NO_DATA_FOUND THEN
RETURN 'Not working';
END;

How to return a table of records from a PLSQL function?

I have a function which is having three different queries. First query is returning a single record in a plsql record type.Second query is returning another single value and third is also returning a different single value. Now I want to append first record with those two values and return a table of that new record from my function. How can I achieve that.
create or replace function test(p_actBillDat date) return <what should I return> as
type tab_accountNum is table of account.account_num%type;
var_accountNum tab_accountNum;
type query1Record is record(
accountNum account.account_num%type,
customerRef customer.customer_ref%type,
internalCreditScore CUSTOMERATTRIBUTES.Internal_Credit_Score%type);
var_query1Rec query1Record;
var_nsfDat date;
var_writeOffdat date;
cursor cur_accountNum is
select ACCOUNT_NUM
from BILLSUMMARY
where trunc(ACTUAL_BILL_DTM) = p_actBillDat
and CANCELLATION_REQUEST_DAT is null;
begin
open cur_accountNum;
Loop
fetch cur_accountNum bulk collect
into var_accountNum limit 100;
close cur_accountNum;
for i in 1 .. var_accountNum.count
loop
select A.ACCOUNT_NUM, A.CUSTOMER_REF, CA.INTERNAL_CREDIT_SCORE
into var_query1Rec
from ACCOUNT A, CUSTOMERATTRIBUTES CA, CONTACTDETAILS CD, CONTACT CNT
where A.ACCOUNT_NUM = var_accountNum(i) and
A.CUSTOMER_REF = CA.CUSTOMER_REF(+) and
A.CUSTOMER_REF = CD.CUSTOMER_REF and
CNT.CUSTOMER_REF = A.CUSTOMER_REF and
CD.CONTACT_SEQ = CNT.CONTACT_SEQ and
CD.CONTACT_SEQ = 1 and
CD.START_DAT = (select min(CNTD.START_DAT)
from CONTACTDETAILS CNTD
where CNTD.CONTACT_SEQ = CD.CONTACT_SEQ and
CNTD.CUSTOMER_REF = A.CUSTOMER_REF);
select max(AP.ACCOUNT_PAYMENT_DAT) into var_writeOffdat
from ACCOUNT A, ACCOUNTPAYMENT AP
where A.ACCOUNT_NUM = AP.ACCOUNT_NUM and
A.ACCOUNT_NUM = var_accountNum(i) AND
A.TOTAL_WRITEOFF_TOT <> 0 and
(AP.PAYMENT_ORIGIN_ID = 2 or AP.PAYMENT_ORIGIN_ID = 3) and
AP.CANCELLED_DTM is null and
AP.FAILED_DTM is null;
select max(PP.FAILED_DTM) into var_nsfDat
from ACCOUNTPAYMENT AP, PHYSICALPAYMENT PP
where AP.ACCOUNT_NUM = var_accountNum(i) and
AP.ACCOUNT_PAYMENT_STATUS = 3 and
AP.PHYSICAL_PAYMENT_SEQ = PP.PHYSICAL_PAYMENT_SEQ and
AP.CUSTOMER_REF = PP.CUSTOMER_REF and
PP.PHYSICAL_PAYMENT_STATUS = 3 and
PP.FAILURE_CODE_ID in (select PFC.FAILURE_CODE
from CGPAYMENTFAILURECONFIG PFC
where PFC.FAILURE_TYPE = 'Decline NSF') ;
<how to appned var_query1Rec with var_writeOffdat and var_writeOffdat>
<how to make a PLSQl table of that record and return from function>
end loop;
end loop;
end;
If this function is not part of a package - why wouldn't it be? then you have no other choice but to declare a SQL Object type like this example:
CREATE TYPE person_typ AS OBJECT (
idno NUMBER,
first_name VARCHAR2(20)
);
Declare the variables at the top of your function to access the type created.
type t_arr is table of person_typ ;
l_arr t_arr := t_arr();
Then assign them in your code:
l_arr.extend;
l_arr(i).idno := xxx;
l_arr(i).first_name := yyyy;
The create function returns the object:
create or replace function test(p_actBillDat date) return person_typ as
.....
return(l_arr);
end;
But I would have this function in a package then in the package body header or spec you could do this:
type t_rec is
record(x number
,y varchar2(100)
);
type t_tbl is table of t_rec index by binary_integer;
Then declare in your function:
l_tbl t_tbl;
Then assign them in the function:
l_tbl(i).x := xxx;
l_tbl(i).y := yyy;
And finally just return the type in your function like this:
create or replace function test(p_actBillDat date) return t_tbl as
......
l_tbl t_tbl;
begin
.......
for i in 1..counter loop
.. SQL statements
l_tbl(i).x := xxx;
l_tbl(i).y := yyy;
end loop;
return l_tbl;
end;

Selecting conditions dynamically In oracle

Hi What I would like to do is take the search criterias as parameters to my function and search through the table depending on the input parameters.. for example: IF ALL the parameters are NULL then the function will return evey field in the table, if a parameter is not NULL that parameter will be a search criteria. I could do an If statement but it would be too long and assuming that I would have had a bigger table it would be very painful, Is there any way I could accomplish this Task? Thanks
My Code:
create or replace type ordersinf as object(orderDate DATE, orderName VARCHAR2(20), orderPrice NUMBER)
create or replace type orders_tab IS TABLE OF ordersinf
and My Code is:
create or replace function execImmFunc(orderDate DATE, orderName in
VARCHAR2, orderPrice in NUMBER) return orders_tab is
Result orders_tab := orders_tab();
begin
SELECT ordersinf(orderDate => orders_Orderdate, orderName => orderName,orderPrice => orders_price)
BULK COLLECT INTO RESULT
FROM orders_table
WHERE orders_Orderdate >= orderDate OR orders_name = orderName OR orders_price = orderPrice ;
return(Result);
end execImmFunc;
Something like this:
CREATE OR REPLACE FUNCTION execImmFunc(
orderDate IN DATE,
orderName IN VARCHAR2,
orderPrice IN NUMBER
) RETURN orders_tab
IS
Result orders_tab;
BEGIN
SELECT ordersinf(
orderDate => orders_OrderDate,
orderName => orders_Name,
orderPrice => orders_price
)
BULK COLLECT INTO Result
FROM orders_table
WHERE ( orderDate IS NULL OR orders_OrderDate >= orderDate )
AND ( orderName IS NULL OR orders_name = orderName )
AND ( orderPrice IS NULL OR orders_price = orderPrice );
RETURN Result;
END execImmFunc;
Is this what you mean
WHERE (orderDate is null OR orders_Orderdate >= orderDate) AND (orderName is null OR orders_name = orderName) AND (orderPrice is null OR orders_price = orderPrice );
If a parameter orderDate is null - the clause passes and is effectively ignored?
Hey I dont have workspace with me but below is a very simple snippet
which can be used for dynamic sql formation as per the input provided.
Hope this helps
SET SERVEROUTPUT ON;
DECLARE
lv_col1 VARCHAR2(100):=123;
lv_col2 VARCHAR2(100):=1;
lv_col3 VARCHAR2(100):=NULL;
lv_col4 VARCHAR2(100):=45;
lv_col5 VARCHAR2(100):=8;
lv_sql LONG;
lv_where LONG;
BEGIN
lv_sql:='SELECT * FROM TABLE WHERE 1 = 1 ';
SELECT DECODE(lv_col1,NULL,'',' AND col1 = '''
||lv_col1
||'''')
|| DECODE(lv_col2,NULL,'',' AND col2 = '''
||lv_col2
||'''')
|| DECODE(lv_col3,NULL,'',' AND col3 = '''
||lv_col3
||'''')
|| DECODE(lv_col4,NULL,'',' AND col4 = '''
||lv_col4
||'''')
|| DECODE(lv_col5,NULL,'',' AND col5 = '''
||lv_col5
||'''')
INTO lv_where
FROM dual;
dbms_output.put_line(lv_sql||lv_where);
END;
Are you trying to set up so a parameter is either returned in the resultset or used in the where-clause? It does not look like you do, but rather you want to return all columns and use parameters in where only when they are not null.
If so, why not just a classic nvl-setup?
SELECT ordersinf(orderDate => orders_Orderdate
,orderName => orderName
,orderPrice => orders_price)
BULK COLLECT INTO RESULT
FROM orders_table
WHERE orders_Orderdate >= nvl(orderDate, orders_Orderdate)
OR orders_name = nvl(orderName, orders_name)
OR orders_price = nvl(orderPrice, orders_price);
I imagine those ORs ought to be AND as you probably want all conditions sent in to be true, but that is purely a desugn/requirement issue.

Resources