How do I execute a procedure from SQL Developer? - oracle

I have a Store Procedure like below and how to execute from SQL Developer?
PROCEDURE CFR.GET_ALL_ERROR_HISTORY
Argument Name Type In/Out Default?
-------------- ---------- ------ --------
T1_CURSOR REF CURSOR OUT
P_QUERY_TYPE NUMBER IN
P_DATE_START DATE IN DEFAULT
P_DATE_END DATE IN DEFAULT
P_COMP_NUMBER NUMBER IN DEFAULT
P_COMP_GROUP_ID NUMBER IN DEFAULT
When running my code in Visual Studio
ORA-06550: line 1, column 7:
PLS-00306: wrong number or types of arguments in call to 'GET_ALL_ERROR_HISTORY'
ORA-06550: line 1, column 7:
PLS-00306: wrong number or types of arguments in call to 'GET_ALL_ERROR_HISTORY'
ORA-06550: line 1, column 7:
PL/SQL: Statement ignored
My VS Code
Dim oracleParameter(3) As OracleParameter
oracleParameter(0) = New OracleParameter()
oracleParameter(1) = New OracleParameter()
oracleParameter(2) = New OracleParameter()
oracleParameter(3) = New OracleParameter()
oracleParameter(0) = cmd.Parameters.Add("T1_Cursor", dbType:=Oracle.ManagedDataAccess.Client.OracleDbType.RefCursor, ParameterDirection.Output)
oracleParameter(1) = cmd.Parameters.Add("p_Date_Start", dbType:=Oracle.ManagedDataAccess.Client.OracleDbType.Date, val:=dteStart, ParameterDirection.Input)
oracleParameter(2) = cmd.Parameters.Add("p_Date_End", dbType:=Oracle.ManagedDataAccess.Client.OracleDbType.Date, val:=dteEnd, ParameterDirection.Input)
oracleParameter(3) = cmd.Parameters.Add("p_Query_Type", dbType:=Oracle.ManagedDataAccess.Client.OracleDbType.Decimal, val:=intQueryType, ParameterDirection.Input)
I am new to procedure and if you can guide me with how to solve this. I can solve all the rest on my own

There's the code way.
In a SQL Worksheet:
begin
CFR.GET_ALL_ERROR_HISTORY(1, sysdate, sysdate+1, 1, 2);
end;
/
Note you'll need to declare a local sys refcursor variable and supply that in the call if you want to catch the value, then you'll use the PRINT command to print the output.
That's not a best practice, using the order of the parameters to dictate what value is assigned to which input...better to use named notation in your call, so similar to
DECLARE
P_EMP_ID NUMBER;
P_START_DATE DATE;
P_END_DATE DATE;
P_JOB_ID VARCHAR2(10);
P_DEPARTMENT_ID NUMBER;
BEGIN
P_EMP_ID := 1;
P_START_DATE := sysdate-365;
P_END_DATE := sysdate;
P_JOB_ID := 'SALES';
P_DEPARTMENT_ID := 101;
ADD_JOB_HISTORY(
P_EMP_ID => P_EMP_ID,
P_START_DATE => P_START_DATE,
P_END_DATE => P_END_DATE,
P_JOB_ID => P_JOB_ID,
P_DEPARTMENT_ID => P_DEPARTMENT_ID
);
END;
/
or
EXEC CFR.GET_ALL_ERROR_HISTORY(1,...)
And there's the GUI way.
Open the procedure from the tree, and hit the Execute button. The nice thing there is, we'll grab that OUT refcursor for you and show you the results.

Related

Error(11,10): PLS-00306: wrong number or types of arguments in call to 'CONSTRUCT'

I am new to plsql i try to run the piece of code but it is giving error and not able to debug
create or replace type final as object ( ename1 varchar2(10), sal1
NUMBER(7,2));--object
create or replace type construct is table of final; /*nested table of
object type */
create or replace function returnmore (empno1 number) /*Function to
return more*/
return construct
AS
vemp construct:=construct();
vename varchar2(10);
vsal1 NUMBER(7,2);
begin
select ENAME,sal into vename,vsal1 from emp where empno=empno1;
vemp.extend;
vemp(1):=construct(vename,vsal1);
return vemp;
end;
But gives me an error
Function SYSTEM.RETURNMORE#loacaDB
Error(11,1): PL/SQL: Statement ignored
Error(11,10): PLS-00306: wrong number or types of arguments in call to 'CONSTRUCT'
I am using oracle10gxe and sqldeveloper4.2
You can prefer using non-preserved keyword such as typ_emp instead of final which's reserved.
SQL> create or replace type typ_emp as object ( ename1 varchar2(10), sal1 number(7,2));
SQL> create or replace type construct is table of typ_emp;
and you can convert your function as below :
create or replace function returnmore( empno1 emp.empno%type )
return construct AS
vemp construct := construct();
vename varchar2(10);
vsal1 number(7, 2);
begin
select ename, sal into vename, vsal1 from emp where empno = empno1;
vemp.extend;
vemp(1) := typ_emp(vename, vsal1);
dbms_output.put_line(vemp(1).ename1);
return vemp;
end;
/
or another way to handle the same operation :
SQL> create or replace function returnmore( empno1 emp.empno%type )
return construct AS
vemp construct := construct();
v_sql varchar2(2000);
begin
v_sql := 'select typ_emp(ename, sal) from emp where empno = :v_empno1';
execute immediate v_sql bulk collect into vemp using empno1;
dbms_output.put_line(vemp(1).ename1);
return vemp;
end;
/
and test by invoking
SQL> set serveroutput on;
SQL> declare
result construct;
begin
result := returnmore( 1 ); -- 1 is just an ordinary presumed value for empno
end;
/ --> this will return the employee name as printed.
P.S. Never ever use SYSTEM user for non-administrative purposes. May be extremely harmful for your database.

How to print a cursor in a PL/SQL block?

I can't seem to print cursor, what am I doing wrong?
DECLARE
LEADEMAIL VARCHAR2(200);
CLIENTID NUMBER;
v_Return ON24MASTER.WEBCAST_REPORTS.ResultSetCursor;
BEGIN
LEADEMAIL := 'nunyo#business.com';
CLIENTID := 22921;
v_Return := WEBCAST_REPORTS.LEAD_BASIC_INFO(
LEADEMAIL => LEADEMAIL,
CLIENTID => CLIENTID
);
DBMS_OUTPUT.PUT_LINE('v_Return = ' || v_Return);
-- :v_Return := v_Return;
END;
I get the following error:
Error report -
ORA-06550: line 14, column 26:
PLS-00306: wrong number or types of arguments in call to '||'
ORA-06550: line 14, column 5:
PL/SQL: Statement ignored
06550. 00000 - "line %s, column %s:\n%s"
*Cause: Usually a PL/SQL compilation error.
*Action:
Most of the code was taken directly from running the function from SQL developer.
This is the package function:
FUNCTION LEAD_BASIC_INFO(
leadEmail VARCHAR2,
clientId NUMBER
) RETURN ResultSetCursor IS
resultSet ResultSetCursor;
email VARCHAR2(1000);
webcastEngagement NUMBER(10,1);
videoEngagement NUMBER(10,1);
documentEngagement NUMBER(10,1);
totalEngagement NUMBER(10,1);
--averageEngagement NUMBER(4,1);
totalWebcastSeconds NUMBER(10);
engagementMinutes NUMBER(10, 1);
last30DaysEM NUMBER(10, 1);
last60DaysEM NUMBER(10, 1);
fromDate DATE;
engagementPrediction NUMBER(10);
BEGIN...
Also, I can't print the result using a select statement because the function has DML as well.
In Oracle 12c, you can use DBMS_SQL.RETURN_RESULT. I.e.,
DECLARE
LEADEMAIL VARCHAR2(200);
CLIENTID NUMBER;
v_Return ON24MASTER.WEBCAST_REPORTS.ResultSetCursor;
BEGIN
LEADEMAIL := 'nunyo#business.com';
CLIENTID := 22921;
v_Return := WEBCAST_REPORTS.LEAD_BASIC_INFO(
LEADEMAIL => LEADEMAIL,
CLIENTID => CLIENTID
);
DBMS_SQL.RETURN_RESULT(v_Return);
END;
SQL*Developer will print the results.
You can't print a cursor like that; it would have to implicitly convert the rows and columns to strings, and that's too much to expect. The dbms_output.put_line() procedure only accepts a string argument - or anything that can be implicitly converted to a string. A cursor cannot.
You would have to loop over the cursor result set, fetching into a suitable record type; and then have a dbms_output call within that loop which concatenates all the column values from the result set (formatted and possibly padded if you're trying to emulate a select) into a single string.
Without know exactly how ON24MASTER.WEBCAST_REPORTS.ResultSetCursor is defined (presumably TYPE ResultSetCursor IS REF CURSOR), or what the query that populates it within your procedure is returning - which column names - it's hard to be more specific.
But since you've tagged this for SQL Developer you can use its built-in handling for ref cursor variables, which is handy:
variable rc refcursor;
DECLARE
LEADEMAIL VARCHAR2(200);
CLIENTID NUMBER;
BEGIN
LEADEMAIL := 'nunyo#business.com';
CLIENTID := 22921;
:rc := WEBCAST_REPORTS.LEAD_BASIC_INFO(
LEADEMAIL => LEADEMAIL,
CLIENTID => CLIENTID
);
END;
/
print rc
Before the block a bind variable rc is declared with the variable command. Inside the block that is used instead of a local v_Return, so that doesn't even need to be declared locally. (Note the colon before :rc in the assignment from the function - that denotes a bind variable). And then after the block the client lets you print the ref cursor. (Those doc links are for SQL*Plus, but they are among the the many commands SQL Developer supports.)
With a dummy package:
create or replace package WEBCAST_REPORTS AS
TYPE ResultSetCursor IS ref cursor;
FUNCTION LEAD_BASIC_INFO(
leadEmail VARCHAR2,
clientId NUMBER
) RETURN ResultSetCursor;
end WEBCAST_REPORTS;
/
create or replace package body WEBCAST_REPORTS AS
FUNCTION LEAD_BASIC_INFO(
leadEmail VARCHAR2,
clientId NUMBER
) RETURN ResultSetCursor IS
resultSet ResultSetCursor;
BEGIN
OPEN resultSet FOR select * from dual;
RETURN resultSet;
END LEAD_BASIC_INFO;
end WEBCAST_REPORTS;
/
then the code I showed above, run as a script, shows this in the script output window:
PL/SQL procedure successfully completed.
D
-
X

Procedure is compiled but when calling procedure and passing parameters I would receive error

I have created procedure for name change but when calling procedure I would receive error:
Error report:
ORA-06550: line 4, column 5:
PLS-00306: wrong number or types of arguments in call to 'PRODCHANGE_SP'
procedure:
create or replace
PROCEDURE PRODCHANGE_SP
(
P_PRODID IN bb_product.idproduct%TYPE
, P_NAME IN OUT bb_product.productname%TYPE
) AS
BEGIN
UPDATE bb_product
SET productname = p_name
WHERE idproduct = p_prodid;
COMMIT;
END PRODCHANGE_SP;
BLOCK, calling procedure to check if is working:
DECLARE
lv_pname_txt bb_product.productname%TYPE;
BEGIN
prodchange_sp(1, 'CapressoBar Model #352', lv_pname_txt);
DBMS_OUTPUT.PUT_LINE(lv_pname_txt);
END;
You need to fetch the old value before you update it. After update, overwrite the out variable with the old value.
create or replace PROCEDURE PRODCHANGE_SP
(
P_PRODID IN bb_product.idproduct%TYPE,
P_NAME IN OUT bb_product.productname%TYPE
) AS
P_NAME_old bb_product.productname%TYPE;
BEGIN
SELECT productname
INTO P_NAME_old
FROM bb_product
WHERE idproduct = p_prodid;
UPDATE bb_product
SET productname = p_name
WHERE idproduct = p_prodid;
COMMIT;
P_NAME := P_NAME_old;
END PRODCHANGE_SP;
You need to pass the value in the same variable as it is IN OUT. Rewrite the code to invoke procedure as below.
DECLARE
lv_pname_txt bb_product.productname%TYPE;
BEGIN
lv_pname_txt := 'CapressoBar Model #352';
prodchange_sp(1, lv_pname_txt);
DBMS_OUTPUT.PUT_LINE(lv_pname_txt);
END;

How to get the values of an OBJECT or ROWTYPE dynamically (Reflection) in Oracle PL/SQL?

I am trying to take a ROWTYPE, RECORD, or OBJECT type and dynamically convert it to a single string representation.
I want to do this dynamically.
Update: Doing this for an OBJECT type now working thanks to Justin Cave's feedback.
Example Data:
ID | VAL
---------
1 | BOB
Desired Output:
ID=1, VAL=BOB
Error Received:
ORA-06550: line 7, column 25:
PLS-00306: wrong number or types of arguments in call to 'TO_STRING'
ORA-06550: line 7, column 4:
PL/SQL: Statement ignored
What I have so Far (Doesn't loop through columns yet.):
CREATE OR REPLACE FUNCTION to_string (
ip_anydata in out anydata --note the "out" - this is required for the "piecewise"
)
RETURN VARCHAR2
IS
lv_typecode PLS_INTEGER;
lv_anytype anytype;
BEGIN
DBMS_OUTPUT.PUT_LINE('[Expected='||dbms_types.typecode_object||', Actual='||ip_anydata.getType(lv_anytype)||']');
--Get the typecode, and the ANYTYPE
lv_typecode := ip_anydata.getType(lv_anytype);
--Check that it's really an object
IF lv_typecode = dbms_types.typecode_object
THEN
--If it is an object, find the first item
DECLARE
lv_first_attribute_typecode pls_integer;
lv_aname varchar2(32767);
lv_result pls_integer;
lv_varchar varchar2(32767);
--Variables we don't really care about, but need for function output
lv_prec pls_integer;
lv_scale pls_integer;
lv_len pls_integer;
lv_csid pls_integer;
lv_csfrm pls_integer;
lv_attr_elt_type anytype;
BEGIN
lv_first_attribute_typecode := lv_anytype.getAttrElemInfo(
pos => 1, --First attribute
prec => lv_prec,
scale => lv_scale,
len => lv_len,
csid => lv_csid,
csfrm => lv_csfrm,
attr_elt_type => lv_attr_elt_type,
aname => lv_aname
);
--Check typecode of attribute
IF lv_first_attribute_typecode = dbms_types.typecode_varchar2
THEN
--Now that we've verified the type, get the actual value.
ip_anydata.piecewise;
lv_result := ip_anydata.getVarchar2(c => lv_varchar);
--DEBUG: Print the attribute name, in case you're curious
--dbms_output.put_line('lv_aname: '||lv_aname);
RETURN lv_aname||'='||lv_varchar;
ELSE
raise_application_error(-20000, 'Unexpected 1st Attribute Typecode: '||lv_first_attribute_typecode);
END IF;
END;
ELSE
raise_application_error(-20000, 'Unexpected Typecode: '||lv_typecode);
END IF;
END;
/
Scenario#1 - Select INTO w/ ROWTYPE:
DECLARE
lv_cv dual%ROWTYPE;
lv_str VARCHAR2(32767);
BEGIN
DBMS_OUTPUT.PUT_LINE('-----------------------------');
SELECT * INTO lv_cv FROM dual WHERE ROWNUM <= 1;
DBMS_OUTPUT.PUT_LINE(to_string(lv_cv));
END;
/
Scenario#2 - FETCH INTO w/ Cursor ROWTYPE:
DECLARE
CURSOR cv_cur IS SELECT * FROM dual WHERE ROWNUM <= 1;
lv_cv cv_cur%ROWTYPE;
lv_str VARCHAR2(32767);
BEGIN
DBMS_OUTPUT.PUT_LINE('-----------------------------');
OPEN cv_cur;
FETCH cv_cur INTO lv_cv;
CLOSE cv_cur;
DBMS_OUTPUT.PUT_LINE(to_string(lv_cv));
END;
/
Scenario#3 - Regular OBJECT: (Updated)
DECLARE
lv_cv T_CODE_VAL_REC := T_CODE_VAL_REC('BOB', 5);
lv_str VARCHAR2(32767);
lv_any ANYDATA;
BEGIN
DBMS_OUTPUT.PUT_LINE('-----------------------------');
lv_any := sys.anydata.ConvertObject(lv_cv);
DBMS_OUTPUT.PUT_LINE(to_string(lv_any));
EXCEPTION WHEN OTHERS THEN
pts2_test_valitation_util.fail(999, CHR(10)||CHR(10)||'Unexpected Error:'||CHR(10)||SQLERRM||CHR(10)||DBMS_UTILITY.FORMAT_ERROR_BACKTRACE);
END;
/

Output results of Oracle stored proc from SQL Developer

I'm trying to call an Oracle stored proc using SQL Developer. The proc outputs results using a sys_refcursor. I right click in the proc window which brings up the Run PL/SQL window. When I choose the proc I want it creates all the input params etc for me. Below is the code I'm using to try and loop through the sys_refcursor and output the results, but I'm getting an error on the 'v_rec v_Return%rowtype;' line :
ORA-06550: line 6 column 9:
PLS-00320: the declaration of the type of this expression is incomplete or malformed.
ORA-06550: line 6 column 9:
PL/SQL: Item ignored
vendor code 6550
I found the looping code on a couple of other websites and it seems to be the way to do it but it's not working for me no matter what I try. Another question - on the DBMS_OUTPUT.PUT_LINE('name = ' || v_rec.ADM) am I referencing the v_rec correctly i.e. is v_rec."column_name" the correct way??
I'm not that used to Oracle and have never used SQL plus. Any suggestions appreciated.
DECLARE
P_CAE_SEC_ID_N NUMBER;
P_PAGE_INDEX NUMBER;
P_PAGE_SIZE NUMBER;
v_Return sys_refcursor;
v_rec v_Return%rowtype;
BEGIN
P_CAE_SEC_ID_N := NULL;
P_PAGE_INDEX := 0;
P_PAGE_SIZE := 25;
CAE_FOF_SECURITY_PKG.GET_LIST_FOF_SECURITY(
P_CAE_SEC_ID_N => P_CAE_SEC_ID_N,
P_PAGE_INDEX => P_PAGE_INDEX,
P_PAGE_SIZE => P_PAGE_SIZE,
P_FOF_SEC_REFCUR => v_Return
);
-- Modify the code to output the variable
-- DBMS_OUTPUT.PUT_LINE('P_FOF_SEC_REFCUR = ');
loop
fetch v_Return into v_rec;
exit when v_Return%notfound;
DBMS_OUTPUT.PUT_LINE('name = ' || v_rec.ADM);
end loop;
END;
Your problem is here:
v_Return sys_refcursor;
v_rec v_Return%rowtype;
v_Return is a cursor variable and has no specific structure (list of columns), so v_Return%rowtype is not a valid record structure to declare v_rec. It is even possible for different calls to the procedure to return cursors with different structures.
You know what you are expecting the structure of the returned cursor to be (but Oracle doesn't) so you need to explicitly define the appropriate record structure e.g.
type t_row is record (empno number, ename varchar2(30));
v_rec t_row;
You need a strongly typed ref cursor to be able to define it as a %ROWTYPE.
Example here
#Tony Andrews thanks for this it gave me a better idea where I was going wrong. Still having problems though - here's a shortened version of my proc. It's a bit complex in that it's selecting all fields from a subquery and 2 other values:
open p_fof_sec_refcur for
SELECT *
FROM(
SELECT securities.*, rownum rnum, v_total_count
FROM
(
SELECT
CFS.CAE_SEC_ID,
CFS.FM_SEC_CODE,
...
FROM
CAEDBO.CAE_FOF_SECURITY CFS
INNER JOIN caedbo.CAE_DATA_SET_ELEMENT CDSE_STAT
ON (CDSE_STAT.DATA_SET_ELEMENT_ID = CFS.APPR_STATUS)
...
WHERE APPR_STATUS = NVL(p_appr_status, APPR_STATUS)
...
)securities
)
WHERE rnum between v_pgStart and v_pgEnd;
I explicitly defined the output structure as below to match the return fields from the proc but I'm still getting an error:
v_Return sys_refcursor;
type t_row is record (CAE_SEC_ID NUMBER,FM_SEC_CODE VARCHAR2(7),...rnum number, v_total_count number);
v_rec t_row;
The error I get is
ORA-06504: PL/SQL: Return types of Result Set variables or query do not match
ORA-06512: at line 45
I'm just wondering is the "rownum rnum, v_total_count" part tripping me up. I'm pretty sure I have all the other fields in the output structure correct as I copied them directly from the proc.

Resources