While executing Sybase procedure from JDBC, I am getting below error:
Execute cursor is declared on a procedure which contains a non-SELECT
or a SELECT with COMPUTE clause. for the declaration of this cursor to
be legal it should have a single select statement without a compute
clause
I am using JCONN4 sybase jar. Does sybase has such restrictions on procedure to not have select statement with compute clause?
Also I searched in Sybase documentation but couldn't get proper answer.
http://infocenter.sybase.com/help/index.jsp?topic=/com.sybase.39996_1250/html/svrtsg/svrtsg348.htm
I cannot post the procedure here, but I can post the sample
create proc sample (#value_date datetime = null) as
begin
if #value_date is null
select #value_date = some_column from some_table
select a,b,c,d into #ad
from
table_a where a='something'
select a,b,c,d case when a=0 then 0 else b/a
from #ad
end
The above procedure is called using sybStatemt.executeQuery function
Looks like its Sybase bug. steps to reproduce the issue
Create a procedure having select with compute clause as i described above
write jdbc program and use belew method
statement.setFetchSize(1000);
Execute the program and you will see the error
now the question is does Sybase really has these kind of restrictions or it is specific to their Driver only and we can say its driver issue ?
You must use CallableStatement when calling store procedure
If you execute a stored procedure in a CallableStatement object that represents parameter values as question marks, you get better performance than if you use both question marks and literal values for parameters. Also, if you mix literals and question marks, you cannot use output parameters with a stored procedure.
The following example creates sp_stmt as a CallableStatement object for executing the stored procedure MyProc:
CallableStatement sp_stmt = conn.prepareCall( "{call MyProc(?,?)}");
The two parameters in MyProc are represented as question marks. You can register one or both of them as output parameters using the registerOutParameter methods in the CallableStatement interface.
In the following example, sp_stmt2 is a CallableStatement object for executing the stored procedure MyProc2.
CallableStatement sp_stmt2 = conn.prepareCall( {"call MyProc2(?,'javelin')}");
Run your sp from sybase command prompt.
If it gives result it should work with sybase driver.
I have used ado.net driver in c# it can run similar queries
https://marketplace.visualstudio.com/items?itemName=CDATASOFTWARE.SybaseADONETProvider
Your Sp looks simple. But i think your sp had some runtime issue.
I think this line
if #value_date is null
select #value_date = some_column from some_table
should be
if #value_date is null
select #value_date = some_column from some_table where col1='kkk' so that only
one value comes
Related
I have been given an oracle procedure with the in out parameter %rowtype,like:
CREATE OR REPLACE PROCEDURE cleansing(
io_user IN OUT USER%rowtype
)
IS
BEGIN
--some pl/sql code
END cleansing;
USER is a table with more than 100 columns, I want to call the procedure by Java.
I can't change the procedure, because they are already used by other project.
I can't add procedure to database, because I don't have the permission to do it.
I google it, but can't find a good way to handle this.
what I want to do is:
1. pass the parameter.
2. get the parameter. some java demo code:
String sql = "{call cleansing(?)}";
try {
dbConnection = getDBConnection();
callableStatement = dbConnection.prepareCall(sql);
callableStatement.setXXX()//I don't know
callableStatement.registerOUTParameter(1, //I don't know the type.);
can anyone help me and give some demo code? no change to database and in out parameter mapping with java
This is possible but it's not really straightforward. You have to create something of type USER%ROWTYPE at runtime and use that to call your stored procedure. Take a look here for details.
To get output values as well, you have to do something extra, along the line of Sumit's comment. Basically, after your procedure call, you open a cursor that selects the relevant data from the USER parameter.
So you get a database statement as follows (pseudocode):
string sql =
"declare
user_param user%rowtype;
begin
-- Set necessary parameters
user_param.col0 := :p0In;
user_param.col1 := :p1In;
...
-- Call procedure.
cleansing(io_user => user_param);
-- Read necessary output values into cursor.
open :pOut for select user_param.col99 as col99
user_param.col98 as col98
...
from dual;
end;"
You call this entire statement the usual way, but you register a cursor out parameter (unfortunately, Java is a very long time ago for me so I'm not sure on the exact syntax).
callableStatement.registerOutParameter("pOut", OracleTypes.CURSOR);
...
callableStatement.execute();
...
ResultSet rs = (ResultSet) callableStatement.getObject("pOut");
// Read from result set.
EDIT: I turned this into a blogpost. Code examples are in C# but the idea is the same.
I have a stored procedure in a postgres database. I'm using the postgres JDBC driver to execute a stored procedure, and I do not care about the return type, and can't execute the query. It's indicating that there's a syntax error near the name of the function.
In procedures that return rows, I've been able to do this via a PreparedStatement and setting the parameters, like:
PreparedStatement prepared = connection.prepareStatement("SELECT * FROM NonQueryProcedure(?)");
prepared.setInt(1, 999);
// ....
ResulSet resultSet = prepared.executeQuery();
However, I can't seem to get this to work for an "update" stored procedure where I don't care about the return type. I've tried using connection.prepareStatement() and prepareCall(), and also tried executing it with statement.execute(), .executeUpdate(), and .executeQuery(), without success.
How can I execute a stored procedure where I don't care about the return type?
As PostgreSQL has no "real" procedures, functions are simply executed using a SELECT statement:
statement.execute("select NonQueryProcedure(?)");
Note that inside a PL/pgSQL function, you can use the perform statement to call such a function. But this is not available outside of a PL/pgSQL block.
Without the actual syntax error, I can't say for sure, but try this:
"SELECT * FROM \"getData\"(?)"
CamelCase/PascalCase is a BAD idea in any SQL database. Either it folds it to a single case and all you see is AMASSOFUNREADABLELETTERS or it requires quoting and you will have to forevermore type "aMassofLettersAndQuotesAndShiftKeysAndMyFingersHurt" anytime you want to avoid a syntax error.
I have a table named employee, which has his id, name, phone number. I am using MySQL as my database. I am using Java Swing for that. I am searching the employee table with name now using Java (I have used like clause in my Java page).
Now I need to implement that function in stored procedures. Is it possible? And how can we take that resultset in Java code, if it is possible??
Now I have written my stored procedure as follows
BEGIN
SELECT * FROM employee where empName like '%su%'
END
Sample code will be appreciated..
Thanks
First thing is you should write msql procedure that sends parameter for LIKE,
CREATE PROCEDURE simpleproc (param1 CHAR(20))
BEGIN
SELECT * FROM employee where empName like param1;
END
Then from java program you can use this code to use procedure,
CallableStatement cstmt = con.prepareCall("{call simpleproc(?)}");
cstmt.setString(1, "%su%");
ResultSet rs = cstmt.executeQuery();
When executing a stored procedure it may actually return multiple ResultSet objects and/or update counts if it does several statements.
You use CallableStatement to execute the proc and then getResultSet() or getUpdateCount() to get the right result. For multiple results sets/statements you call getMoreResults() to move through the results of the stored proc.
For a simple case like this you should just need to call getResultSet() once and process it.
Yes you can. A stored procedure can even return multiple resultsets.
DELIMITER $$ -- recognized by mysql client but not phpmyadmin
CREATE PROCEDURE prc_test()
BEGIN
SELECT *
FROM employee
WHERE empName LIKE '%su%';
END;
$$
DELIMITER ;
CALL prc_test(); -- to call
Using the JDBC driver provided by Microsoft (sqljdbc4.jar) I am unable to call a stored procedure using a synonym defined for it.
I.e. for a synonym defined as:
CREATE SYNONYM dbo.synonym_name for dbo.procedure_name
when running the callable statement created by:
CallableStatement callStmt = conn.prepareCall("{ call [dbo].[synonym_name] (?,?,?,?,?,?) }");
I get an exception:
Exception in thread "main" com.microsoft.sqlserver.jdbc.SQLServerException: Parameter param_name was not defined for stored procedure [dbo].[synonym_name].
at com.microsoft.sqlserver.jdbc.SQLServerException.makeFromDriverError(SQLServerException.java:171)
at com.microsoft.sqlserver.jdbc.SQLServerCallableStatement.findColumn(SQLServerCallableStatement.java:1217)
at com.microsoft.sqlserver.jdbc.SQLServerCallableStatement.setString(SQLServerCallableStatement.java:1563)
at testmssql.main(testmssql.java:53)
Even though the parameters are correctly set (if I call the procedure directly (bypassing the synonym) everything works fine).
Further more, if I replace Microsoft's driver with JTDS, everything works fine.
How can one run a CallableStatement using a synonym for a stored procedure with Microsoft SQL Server's JDBC driver?
SQL Server Synonyms do not have query-able metadata. Judging by the error, JDBC is trying to confirm that the parameters declared in the Java code match the parameters declared on the stored procedure. That fails because of the missing metadata.
The only way around this is to create a passthrough stored procedure instead of the synonym.
So if you have this procedure:
CREATE PROCEDURE dbo.RealProcedure
#p1 INT,
#p2 INT
AS
BEGIN
RAISERROR('TODO: implement me',16,10);
END
And you have this synonym:
CREATE SYNONYM dbo.myProcedure FOR dbo.realProcedure;
Drop the synonym and create this procedure instead:
CREATE PROCEDURE dbo.myProcedure
#p1 INT,
#p2 INT
AS
BEGIN
EXEC dbo.realProcedure #p1,#p2;
END
There is a similar issue described here: http://social.msdn.microsoft.com/Forums/en-us/sqldataaccess/thread/dcdfee17-a926-4b57-8641-ed86fec989f2
I have been trying to execute a MS SQL Server stored procedure via JDBC today and have been unsuccessful thus far. The stored procedure has 1 input and 1 output parameter. With every combination I use when setting up the stored procedure call in code I get an error stating that the stored procedure couldn't be found. I have provided the stored procedure I'm executing below (NOTE: this is vendor code, so I cannot change it).
set ANSI_NULLS ON
set QUOTED_IDENTIFIER ON
GO
ALTER PROC [dbo].[spWCoTaskIdGen]
#OutIdentifier int OUTPUT
AS
BEGIN
DECLARE #HoldPolicyId int
DECLARE #PolicyId char(14)
IF NOT EXISTS
(
SELECT *
FROM UniqueIdentifierGen (UPDLOCK)
)
INSERT INTO UniqueIdentifierGen VALUES (0)
UPDATE UniqueIdentifierGen
SET
CurIdentifier = CurIdentifier + 1
SELECT #OutIdentifier =
(SELECT CurIdentifier
FROM UniqueIdentifierGen)
END
The code looks like:
CallableStatement statement = connection
.prepareCall("{call dbo.spWCoTaskIdGen(?)}");
statement.setInt(1, 0);
ResultSet result = statement.executeQuery();
I get the following error: SEVERE: Could not find stored procedure 'dbo.spWCoTaskIdGen'.
I have also tried
CallableStatement statement = connection
.prepareCall("{? = call dbo.spWCoTaskIdGen(?)}");
statement.registerOutParameter(1, java.sql.Types.INTEGER);
statement.registerOutParameter(2, java.sql.Types.INTEGER);
statement.executeQuery();
The above results in: SEVERE: Could not find stored procedure 'dbo.spWCoTaskIdGen'.
I have also tried:
CallableStatement statement = connection
.prepareCall("{? = call spWCoTaskIdGen(?)}");
statement.registerOutParameter(1, java.sql.Types.INTEGER);
statement.registerOutParameter(2, java.sql.Types.INTEGER);
statement.executeQuery();
The code above resulted in the following error: Could not find stored procedure 'spWCoTaskIdGen'.
Finally, I should also point out the following:
I have used the MS SQL Server Management Studio tool and have been able to successfully run the stored procedure. The sql generated to execute the stored procedure is provided below:
GO
DECLARE #return_value int;
DECLARE #OutIdentifier int;
EXEC #return_value = [dbo].[spWCoTaskIdGen] #OutIdentifier = #OutIdentifier OUTPUT;
SELECT
#OutIdentifier [#OutIdentifier],
#return_value [Return Value];
GO
The code being executed runs with the same user id that was used in point #1 above.
In the code that creates the Connection object I log which database I'm connecting to and the code is connecting to the correct database.
Any ideas?
Thank you very much in advance.
Most likely one of...
The credentials uses have no rights to run the code. You'd need a GRANT EXECUTE in the script above
Wrong database. For example, the stored proc was created in master but you are connected to "MyDB"
Since it can't even find the procedure, I would first look to make sure that your user has execute privileges for that procedure. You could try executing the proc with the same user from a tool like Squirrel.
Try it without the dbo. owner designation:
CallableStatement statement = connection.prepareCall("? = spWCoTaskIdGen(?)");
statement.registerOutParameter(1, java.sql.Types.INTEGER);
statement.registerOutParameter(2, java.sql.Types.INTEGER);
statement.executeQuery();
Also, and this is a longshot, are you sure you're in the correct database within the database server?
I had the same problem using SQLServer 2012 Express.
I solved it starting the "SQL Server Browser" service.
Have you tried changing your Java code to use "exec" instead of "call"?
That is:
CallableStatement statement = connection
.prepareCall("{exec dbo.spWCoTaskIdGen(?)}");