Oracle PL/SQL: calling stored procedure with parameters - sql

I have created a stored procedure and compiled it successfully without any errors. However, when I call it within an annoynmous block, it returns an error message PLS-00201: identifier 'DUE_FOR_RAISE' must be declared.
What seems to be wrong? Is there something wrong with the procedure calling?
This is what I used to call the procedure:
BEGIN due_for_raise('Austin'); END;

It's because you've quoted your procedure name (never do this). You need to call it with quotes and exactly the same casing as you used to name the procedure, so:
BEGIN
"due_for_raise"('Austin');
END;
If would be easier to drop your old procedure, and re-create it without a quoted name.
To quote from the documentation on Database Object Names and Qualifiers:
Oracle does not recommend using quoted identifiers for database object names. These quoted identifiers are accepted by SQL*Plus, but they may not be valid when using other tools that manage database objects.

Related

Execute Snowflake Procedure in Matilion

I'm trying to execute Snowflake Stored Procedure in Matilion Using Sql Script component.
But i'm getting error as Unknown user defined function.
Can someone help me to call the procedure using Matilion Job.
Thank You !
That looks like a name resolution error. Snowflake does not recognize the name of the stored procedure. You will see the same generic error message when trying to call a procedure that really does not exist...
You most likely need to
qualify the procedure name with a database and a schema
put the names inside double-quotes if they are case sensitive.
In the Matillion stored procedure article there is an example CALL "${environment_database}"."${examples_schema}"."audit"('START', ${run_history_id}, NULL)

PLS-00306: wrong number or types of arguments in call to - Error

I am getting following error when calling a oracle plsql procedure using spring jdbc in java.
org.springframework.jdbc.BadSqlGrammarException: CallableStatementCallback; bad SQL grammar [{call "Procedure name"; nested exception is java.sql.SQLException: ORA-06550: line 1, column 7:
PLS-00306: wrong number or types of arguments in call to 'procedure_name'
ORA-06550: line 1, column 7:
PL/SQL: Statement ignored
This procedure exist under a package A in schema S1. I have created a synonym in schema S2 for this package A and trying to execute this procedure using spring SimpleJdbcCall, with schema name S2 but it's giving me the above error.
But when i execute this query using SqlPlus in schema S2, this procedure executes fine, it means there is no grant issue with this.
When i execute the same procedure with the Schema name where it actually exists (S1) then also it executes fine using spring-java.
Is there any issue related to synonym created in Schema S2 for this package A??
Am i missing anything here?
I hit the same issue and like you explicitly declared the parameters. The fix was to additionally specify:
new SimpleJdbcCall(dataSource)
.withoutProcedureColumnMetaDataAccess()
...
My assumption is that the synonym is preventing the parameter inference from working without actually stopping it happening and as a result the driver concludes that the stored procedure does not accept any parameters and therefore does not send any.
Old question so I know this won't help the OP but hopefully it helps someone.
Without seeing your code (both the PLSQL and Java side), I would have to say that the procedure has required parameters (no DEFAULT value for a parameter) that you are not supplying in the Java code or the name of the parameter in the procedure does not match the name you used in Java.
Procedure Spec
PROCEDURE procedure1(value OUT NUMBER,
userId IN NUMBER,
returnCursor OUT PackageA.Types.cursorType);
Java-Code
SimpleJdbcCall optOutCall = new SimpleJdbcCall(dataSource)
.withSchemaName("Schema-A")
.withCatalogName("PackageA")
.withProcedureName(procedure1)
.declareParameters(new SqlOutParameter("value", Types.NUMERIC),
new SqlParameter("userId", Types.NUMERIC))
.returningResultSet("returnCursor", new UserMapper(EnumType.EMAIL, userId));
This "procedure1" exists in Schema-B but i have created a synonym for this procedure in Schema-A and i am trying to execute this procedure
using 'Schema-A' but it throws error, if i give the schema name "Schema-B" in java code then it executes correctly and returns the results.

Oracle SQL Stored Procedures Call vs. Execute

Problem
I'm trying to understand the difference between Oracle SQL commands CALL and EXECUTE.
I've been using CALL to kick off stored procedures but in talking with another developer I found that he almost exclusively uses EXECUTE. I did some research online to see if I was doing something incorrectly but I'm not seeing the clear distinction between the two commands and people seem to use them interchangeably.
Based on the documentation, they seem remarkably similar (at least in terms of interacting with stored procedures).
http://docs.oracle.com/cd/B19306_01/server.102/b14200/statements_4008.htm
http://docs.oracle.com/cd/B19306_01/server.102/b14357/ch12022.htm
http://docs.oracle.com/cd/B28359_01/olap.111/b28126/dml_app_dbms_aw026.htm
It does look like CALL is a universal SQL command while EXECUTE seems to be proprietary so I would be inclined to use CALL over EXECUTE but then again I don't know what that means in regards to performance.
Questions
Is one preferable over the other in terms of kicking off a stored procedure? Does it matter?
If it does matter, what is a situation where either is appropriate?
Are there any performance differences between the two? What's best practice?
Both EXEC[ute] SP() and CALL SP() could be used in SQL*Plus to execute an SP. BTW, you can also use BEGIN SP(); END;
But there are some differences.
CALL is Oracle SQL and should work everywhere. Other DB clients that can talk to Oracle may or may not support SQL*Plus EXEC. Many do (for example, Oracle SQL Developer, SQLWorkbench/J), but some don't (Liquibase).
The data types of the parameters passed by the CALL statement must be SQL data types. They cannot be PL/SQL-only data types such as BOOLEAN.
EXEC could be used to execute not only an SP, but an arbitrary statement.
If an SP does not have parameters, you can use EXEC SP; syntax, but CALL requires empty parentheses: CALL SP();
If you are calling a proc that returns a sys_refcursor using Toad, there is a difference between CALL and EXEC.
create procedure foo(i in number,o out sys_refcursor)
as
begin
open o for
select i from dual;
end;
exec foo(1,:r); -- outputs 1 row
call foo(1,:r); -- outputs 0 rows
-- Note: when you prefix a parameter with a colon, Toad will prompt you for the type (which in this case is a cursor).

Calling a stored procedures within the same schema from a SP

How can I call a stored procedure in the same schema without specifying the full schema name when coding another stored procedure. These are SQL PL procedures within DB2.
First SP:
CREATE PROCEDURE MYSCHEMA.SP_TEST
LANGUAGE SQL
BEGIN
END
Creating a SP calling this SP directly without a schema name causes a compilation error:
CREATE PROCEDURE MYSCHEMA.SP_TEST2
LANGUAGE SQL
BEGIN
CALL SP_TEST();
END
It will throw:
No authorized routine named "SP_TEST" of type "PROCEDURE" having compatible arguments was found.. SQLCODE=-440, SQLSTATE=42884, DRIVER=3.53.71
Directly giving the full schema name works:
CREATE PROCEDURE MYSCHEMA.SP_TEST2
LANGUAGE SQL
BEGIN
CALL MYSCHEMA.SP_TEST();
END
However if I ever move to a different schema I will have to replace that references all over the place. Is there a suitable workaround or nicer solution to the problem?
The CURRENT PATH special register is used to resolve calls to unqualified stored procedures and functions. CURRENT SCHEMA is used to resolve unqualified object names.
By default, CURRENT PATH has IBM functions plus your AUTHID:
$ db2 "values substr(current path,1,60)"
1
------------------------------------------------------------
"SYSIBM","SYSFUN","SYSPROC","SYSIBMADM","IBJORHOV"
1 record(s) selected.
You can modify this with the SET CURRENT PATH statement.
When you create a stored procedure, DB2 takes note of the value of CURRENT PATH at compilation time and uses them to resolve unqualified stored procedure and function calls within the stored procedure. The same logic applies for CURRENT SCHEMA and unqualified table names.
So the proper way to allow unqualified procedure and function calls within a stored procedure is to set the CURRENT PATH register and then creating the procedure.
Ommitting SCHEMA name is discouraged. Keep your schema names in your calls. If you move to a different schema, you have to do this by extracting/altering the SQL script anyway.
The SET SCHEMA command allows you to change the current schema:
SET CURRENT SCHEMA FOO;
CALL MY_PROC_THAT_RESIDES_IN_FOO();
It is not so easy to use set the schema to a dynamic value, though. You would have to either:
Do something with host variables (if you are within a calling application) or
Build and execute a dynamic SQL statement string.
At that point it is probably becoming more trouble than it's worth.
More information can be found at the documentation for the SET SCHEMA command.

What is "*;1" in TADOStoredProc.ProcedureName value in Delphi?

You may specify TADOStoredProc.ProcedureName in Delphi with the following value:
MSSQLProcedureName;1
But what does meen ";1" in this value?
Thanks for the help!
This is an optional value that can be used to specify multiple definitions for the same stored procedure name... I think that the original intention was to allow versioning, but I've never seen it used that way in the wild.
When you don't specify the number in the create procedure statement, it defaults to 1. Some of the various data access layers that call SQL Server will explicitly add the ;1 when executing the stored procedure.
From MSDN:
;*number*
Is an optional integer used to group procedures of the same name so
they can be dropped together with a single DROP PROCEDURE statement.
For example, the procedures used with an application called orders may
be named orderproc;1, orderproc;2, and so on. The statement DROP
PROCEDURE orderproc drops the entire group. If the name contains
delimited identifiers, the number should not be included as part of
the identifier; use the appropriate delimiter around procedure_name
only.