We have a user-defined datatype in Oracle which is used in a procedure as an input argument. We are trying to call this procedure from Pro*C.
In Oracle, the user-defined data type is VARRAY(21) of VARCHAR2(500).
In Pro*C we tried similar to the sample program 9 in https://docs.oracle.com/cd/B12037_01/appdev.101/a97269/pc_07pls.htm#i2344
On compiling we are getting the error "Wrong number or types of arguments in call". Pro*C code
Any help on how to pass an array to a procedure is appreciated.
Pay attention that this declaration is happening into an EXEC SQL EXECUTE block, while you're doing it into a DECLARE SECTION.
Do the declaration and assignment like this:
EXEC SQL EXECUTE
DECLARE
/* your declaration here*/
BEGIN
/* call to the procedure here*/
END;
END-EXEC;
Related
I am trying to test a newly created stored procedure in Oracle.
I added the stored procedure to the package and successfully compiled it. The input parameter is a record type.
This is the script:
SET serveroutput on;
DECLARE
p_trlr_rec trailer%ROWTYPE;
BEGIN
/* Call procedure within package, identifying schema if necessary */
TMS_SL_SQL_TRAILER.PR_UPDATE_DUE_INFO(p_trlr_rec);
END;
I get the error:
PLS-00306: wrong number or types of arguments in call to 'PR_UPDATE_DUE_INFO'
In the package file, the parameter is defined like this:
PROCEDURE PR_UPDATE_DUE_INFO
(p_rec IN OUT rectype_trailer);
PROCEDURE PR_UPDATE_DUE_INFO
(p_rec IN OUT rectype_trailer);
I also tried adding the TYPE definition:
PROCEDURE PR_UPDATE_DUE_INFO
(p_rec IN OUT rectype_trailer);
but I get the same error.
Why won't the script recognize the record definition?
Well the script is recognizing your record definitions, both of them. The calling routine is passing a parameter of type "trailer%ROWTYPE" but your procedure is expecting a type of "rectype_trailer" Even if "rectype_trailer" is defined elsewhere they are not the same; thus the error is wrong type of argument.
You need to change one of them to match the other. Assuming the rowtype definition is correct you need to change the procedure definition to
PROCEDURE PR_UPDATE_DUE_INFO
(p_rec IN OUT trailer%ROWTYPE);
In short the calling parameter definition must exactly match the called procedure definition.
PROCEDURE PR_UPDATE_DUE_INFO
(p_rec IN OUT rectype_trailer);
So for this to compile you must have declared that record type somewhere, hopefully in the specification of the package TMS_SL_SQL_TRAILER. So you simply need to reference that declaration in the calling code:
DECLARE
p_trlr_rec TMS_SL_SQL_TRAILER.rectype_trailer;
BEGIN
/* Call procedure within package, identifying schema if necessary */
TMS_SL_SQL_TRAILER.PR_UPDATE_DUE_INFO(p_trlr_rec);
END;
Oracle PL/SQL strictly enforces data typing. Two different types with identical structures are two different types and the compiler regards them as incompatible. So the compiler hurls when it tries to parse your calling code even if TMS_SL_SQL_TRAILER.rectype_trailer is declared as being of trailer%ROWTYPE.
I am trying to understand how to use multiple procedures in APEX SQL script. First I don't really need stored procedure, but not sure how to declare simple procedure in APEX SQL script. So this is my attempt:
create or replace procedure test1 as
begin
DBMS_OUTPUT.ENABLE;
dbms_output.put_line('test1');
end;
execute test1;
This gives me an error:
Error at line 7: PLS-00103: Encountered the symbol "EXECUTE"
So questions - how to create regular/not stored/ procedures in one SQL script and then call them. What is the entry point of execution in APEX SQL script?
UPD (At the first time I understood question totally wrong)
Correct version of a script:
create or replace procedure test1 as
begin
DBMS_OUTPUT.ENABLE;
dbms_output.put_line('test1');
end;
/
begin
test1;
end;
/
Documentation says, that script can contain inly SQL and PL/SQL commands. Commands of sqlplus will be ignored.
OLD VERSION (Let stay here)
In APEX pages you can use PL/SQL anonymous blocks. For example, you can create process (APEX has some types of them) or PL/SQL region, and use following:
declare
...
begin
some_proc(:P_MY_ITEM);
end;
Here you can invoke any procedure and do anything else that allowed by PL/SQL. Also you can use parameters like :P_ITEM_NAME to get and set values of page and application items.
I have this simple stored procedure that I wrote and executed in PL/SQL.
CREATE OR REPLACE PROCEDURE test_sp
IS
BEGIN
dbms_output.put_line('Test');
END;
I am trying to call it within PL/SQL like this:
CALL test_sp;
But I end up getting this error:
ORA-06576: not a valid function or procedure name
This is a simple call, is there a syntax error or am I missing some kind of permission?
If you are using call then you will want to include parentheses. The oracle docs show call using these:
call test_sp();
Or you can use exec:
exec test_sp;
Or you can just wrap your stored procedure name in an anonymous block:
begin
test_sp;
end;
I need a generalized method to get list of runtime parameters (values) when I call a procedure. I need something similar to the $$PLSQL_UNIT that returns the name of the running procedure.
(plsql Oracle 10g)
E.g. look at this sample procedure:
(it simply prints its own name and parameters )
CREATE OR REPLACE PROCEDURE MY_PROC(ow in varchar2, tn IN varchar2)
IS
BEGIN
dbms_output.put_line('proc_name: '||$$PLSQL_UNIT||' parameters: '|| ow||' '||tn );
EXCEPTION
WHEN OTHERS THEN
DBMS_OUTPUT.PUT_LINE('ERRORE: ' ||SQLERRM);
END MY_PROC;
/
Running procedure produces the following output:
SQL>
1 BEGIN
2 IBAD_OWN.MY_PROC('first_par', 'second_par');
3 END;
4 /
proc_name: MY_PROC parameters: first_par second_par
PL/SQL procedure successfully completed.
I'm not satisfy because I can't copy and paste in all my procedures because I have to hard code each procedure to set their right parameter variables.
Thanks in advance for the help.
It isn't possible to dynamically retrieve the values of parameters passed to a procedure in Oracle PL/SQL. The language simply isn't designed to handle this kind of operation.
Incidentally, in a procedure that is located within a package, $$PLSQL_UNIT will only return the package's name. I find it's better to define a consistently-named constant within each procedure that contains the procedure's name.
When I wanted the same functionality as yours I didn't find any good built-in solution.
What I did is: wrote DB-level trigger which modifies original body of function/procedure/package.
This trigger adds immediatly after "begin" dynamically generated piece of code from "user_arguments".
Plus, after that I include into this trigger the code, that logs calls of procs when exception occures.
Plus, you can trace procs calls, and many more interisting things.
But this solution works fine only for preproduction because performance decreases dramatically.
PS. Sorry for my bad English.
I have an oracle stored proc with signiture: (part of package: Contractor)
PROCEDURE usp_sel_contractors(g_contractors OUT sel_contractor);
I am trying to execute it like:
execute Contractor.usp_sel_contractors;
I'm used to MSSqlServer. This seems like it should be strait forward.
I keep getting error:
Invalid Sql Statement
Thanks!
Assuming sel_contractor is a ref cursor type, you could do this in SQL Plus:
var rc refcursor
exec usp_sel_contractors(:rc)
print rc
I'm not sure why you'd be getting that specific error message, but the obvious problem is that the procedure has a parameter and you're not passing one. Since it's an OUT parameter you would need to pass a variable of the appropriate type which will be populated by the procedure.
For example:
DECLARE
my_contractors sel_contractor;
BEGIN
usp_sel_contractors( my_contractors );
// Do something with the contents of my_contractors here
END;
/