Link to home
Start Free TrialLog in
Avatar of JDCam
JDCam

asked on

Oracle Function as query

Experts,
I want to modify an existing Oracle function. To test my modifications I am trying to run it as a query.
The function relies on 4 input parameters. What is the best method for me to set static values to these inputs allowing me to run it as a query.  

Below are the top 20 lines where the input parameters are declared and the query begins (500+ lines total)

create or replace FUNCTION F4CART5_JDS(
  in_COMP_CODE IN VARCHAR2,
  in_DOC_NUM   IN NUMBER,
  in_CART_ID   IN VARCHAR2,
  in_DOC_CODE   IN VARCHAR2)
  RETURN SYS_REFCURSOR
AS
  ret_CURSOR SYS_REFCURSOR;
BEGIN
  OPEN ret_CURSOR FOR
    select * from (   
SELECT distinct '' LABEL_COUNT, '' LABEL_TOTAL, CUST_NAME, CUST_STAT,
                CUST_ADD1, CUST_ADD2, CUST_ADD3,
                ZIP_CITY, STATE_CODE, M_ZIP.ZIP_CODE,
(CASE WHEN (H.CON_CODE = '/')
THEN (select C_Doc_Man.DOC_MAN_NAME from C_Doc_Man where 1 = 1

Open in new window

Avatar of slightwv (䄆 Netminder)
slightwv (䄆 Netminder)

Just select from it providing literals?

Here is a simple test case:
create or replace function myfunc(p_1 in varchar) return sys_refcursor
is
	ret_cursor SYS_REFCURSOR;
begin
	open ret_cursor for 'select ''Hello '' || :p_1 from dual' using p_1;
	return ret_cursor;
end;
/

show errors

select myfunc('World') from dual;

Open in new window

Avatar of JDCam

ASKER

Slightwv,
Yes, I can call the function with specified values
select DELFOUR.F4CART5_JDS ('W1', 994563, null,'IBAP') from dual

Open in new window

To make any edits to query, this would require me to re-create the function under another name, then edit/test the copy. When run like this the output is a massive single string 

What I was hoping to do was cut/paste the query portion and run as a regular query while still passing the inputs. When run this way, i would get proper rows and columns returned to better scrutinize the results returned.
Take the select from the function, add a parameters CTE and cross join to that.

Using the function I posted above, I get:
with parameters as (
	select 'World' p_1 from dual
)
			select 'Hello ' || p_1 from dual
cross join parameters
;

Open in new window

Avatar of JDCam

ASKER

I am much closer.
This is a very old function written by others. I am getting an error because the cross join to parameters is not compatible with the old school joins used throughout the function.

ORA-25156: old style outer join (+) cannot be used with ANSI joins
25156. 00000 -  "old style outer join (+) cannot be used with ANSI joins"
*Cause:    When a query block uses ANSI style joins, the old notation
           for specifying outer joins (+) cannot be used.
*Action:   Use ANSI style for specifying outer joins also.

FROM M_CUST_H, M_ZIP, C_CART_H CH, M_CON_H CON, E_ORD_H H, M_COMP_H COMP
cross join parameters
WHERE
H.COMP_CODE = COMP.comp_code
and CH.comp_code = H.comp_code
and CH.CART_ID in (select distinct cart_id from c_cart_d where comp_code = in_COMP_CODE and ord_num = in_DOC_NUM and cart_id = nvl(in_CART_ID, cart_id))
and CON.comp_code (+)= H.comp_code
and CON.con_code (+)= H.con_code

Open in new window

I replaced the old style join with LEFT join, but now the columns in that table are not recognized.
ORA-00904: "H"."CON_CODE": invalid identifier
FROM M_CUST_H, M_ZIP, C_CART_H CH, E_ORD_H H, M_COMP_H COMP
LEFT JOIN M_CON_H CON ON CON.COMP_CODE = H.COMP_CODE and CON.CON_CODE = E_ORD_H.con_code
cross join parameters
WHERE
H.COMP_CODE = COMP.comp_code
and CH.comp_code = H.comp_code
and CH.CART_ID in (select distinct cart_id from c_cart_d where comp_code = in_COMP_CODE and ord_num = in_DOC_NUM and cart_id = nvl(in_CART_ID, cart_id))
AND M_CUST_H.COMP_CODE = H.COMP_CODE
AND M_CUST_H.CUST_CODE = H.CUST_CODE

Open in new window


I am getting into major edits where i wasnt intending.
Instead, can I make the 'cross join parameters' old school to work with the rest of the query? 

Then use the old school way to get a cartesian product:
with parameters as (
	select 'World' p_1 from dual
)
			select 'Hello ' || p_1 from dual
,parameters
;

Open in new window



If you are using sqlplus or SQL Developer you can also just use variables.  This will require some tweaking of the select you have that you'll need to remember to correct but shouldn't require modifying joins and CTEs:
var p_1 varchar2(10)
exec :p_1 := 'World';

select 'Hello ' || :p_1 from dual;

Open in new window



>>I replaced the old style join with LEFT join,

You would need to replace all joins to the new ANSI syntax.  Honestly, I probably would.  I find them much easier to read and understand than the old way.
This question needs an answer!
Become an EE member today
7 DAY FREE TRIAL
Members can start a 7-Day Free trial then enjoy unlimited access to the platform.
View membership options
or
Learn why we charge membership fees
We get it - no one likes a content blocker. Take one extra minute and find out why we block content.