I am working with postgresql procedures and trying to call a procedure from my JDBC program. But getting runtime exception saying procedure doesn't exist eventhough I cross-checked and verified that the procedure name is correct.
This is what I am doing
CallableStatement cs = connection.prepareCall("{call proc1()}");
cs.executeUpdate();
And here's my proc1 procedure
create or replace procedure proc1()
as
begin
insert into employee_info values(1,'johnny','1111',43);
-----
end
This is what the output is
Connection Failed! ERROR: function proc1() does not exist
Hint: No function matches the given name and argument types. You might need to add explicit type casts.
I dont understand why its not working eventhough proc1() exists in database.
And what should i Cast?
Add correct schema name to callable statement and it shall work. Please refer to below code for example.
CallableStatement cs = connection.prepareCall("{call yoursSchema.proc1()}");
Finally, I got the solution. The main problem was with JDBC Driver which I downloaded from the official website. I was using the
postgresql driver. I dont know what's wrong with it but It seems like it is not supporting proedures. So I switched to EnterpriseDB(EDB) driver. Now the same program works fine and procedures are getting executed.
I just made these changes
1)Changing Driver
2)Changing Driver Class url from "org.postgresql.Driver" to "com.edb.Driver"
3)Dabase url "jdbc:postgresql://host:port/db to "jdbc:edb://host:port/db"
That's all. Now the procedures works too.
Related
My code is simple
CallableStatement stmt = Conn.prepareCall ("{call Reconciliation (?)}");
stmt.setString(date);
PS.executeUpdate();
Am using Sybase (Adaptive Server Enterprise/15.7.0) and jconnect4 drivers if it is relevant to solution.
My procedure(Reconcliliation) is quite huge so I couldn't post it here but it does some updates to some 1 tables (Recon) after some comparison of data from another 2 tables (Deals1 and Deals2). It do not return any out parameters in procedure, it takes only 1 in parameter which is date.
When I run java code and run the procedure using callable statement it produces some updates data in table (Recon, count is 500) and the error I get after that is this :
java.sql.SQLException: JZ0P1: Unexpected result type.
at com.sybase.jdbc3.jdbc.ErrorMessage.raiseError(Unknown Source)
at com.sybase.jdbc3.jdbc.SybStatement.updateLoop(Unknown Source)
at com.sybase.jdbc3.jdbc.SybStatement.executeUpdate(Unknown Source)
at com.sybase.jdbc3.jdbc.SybCallableStatement.executeUpdate(Unknown
Source)
at DBConnection.ExecuteProc(DBConnection.java:88)
Am pretty sure there is no error in my procedure (Reconciliation) because when I run the same procedure in Aqua Data Studio with command exec Reconciliation '04-Dec-2016' it doesn't give any error and produces full update in tables (Recon, total count is 800).
There is no error in java as well because it is giving sql exception. If am not wrong there must be some problem in middle i.e jconnect drivers or something else.
Please help me with this, thanks in adv.
Old question, but I couldn't find any good answers to this question online when I had the same problem.
The big hint came from http://infocenter.sybase.com/help/index.jsp?topic=/com.sybase.infocenter.dc39001.0700/html/prjdbc0700/CHDGJJIG.htm
JZ0P1 Unexpected result type.
Description: The database has returned a result that the statement cannot
return to the application, or that the application is not expecting at this
point. This generally indicates that the application is using JDBC incorrectly
to execute the query or stored procedure. If the JDBC application is connected
to an Open Server application, it may indicate an error in the Open Server
application that causes the Open Server to send unexpected sequences of results.
The stored procedure is returning tables. Don't do:
PS.executeUpdate();
But do this instead:
ResultSet rs = callableStatement.executeQuery();
For old jdbc drivers, I´ve noticed that
PS.executeUpdate();
raises this error while
PS.execute();
does not
I am attempting to use zxJDBC to connect to a database running on SQL Server 2008 R2 (Express) and call a stored procedure, passing it a single parameter. I am using jython-standalone 2.5.3 and ideally do not want to have to install additional modules.
My test code is shown below.
The database name is CSM
Stored Procedure:
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
-- =============================================
-- Author: <Author,,Name>
-- Create date: <Create Date,,>
-- Description: <Description,,>
-- =============================================
CREATE PROCEDURE dbo.DUMMY
-- Add the parameters for the stored procedure here
#carrierId VARCHAR(50)
AS
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;
-- Insert statements for procedure here
INSERT INTO dbo.carrier (carrierId, test)
VALUES (#carrierId, 'Success')
END
GO
Jython Script:
from com.ziclix.python.sql import zxJDBC
conn = None
try :
conn = zxJDBC.connect('jdbc:sqlserver://localhost\SQLEXPRESS', 'sa', 'password', 'com.microsoft.sqlserver.jdbc.SQLServerDriver')
cur = conn.cursor()
cur.callproc(('CSM','dbo','DUMMY'), ['carrier1'])
conn.commit()
except Exception, err :
print err
if conn:
conn.rollback()
finally :
if conn :
conn.close()
By using cur.execute() I have been able to verify that the above is successfully connecting to the database, and that I can query against it. However, I have thus far been unable to successfully call a stored procedure with parameters.
The documentation here(possibly out of date?) indicates that callproc() can be called with either a string or a tuple to identify the procedure. The example given -
c.callproc(("northwind", "dbo", "SalesByCategory"), ["Seafood", "1998"], maxrows=2)
When I attempt to use this method, I receive the following error
Error("Could not find stored procedure 'CSM.DUMMY'. [SQLCode: 2812], [SQLState: S00062]",)
It would appear that zxJDBC is neglecting to include the dbo part of the procedure identifier.
If I instead call callproc with "CSM.dbo.DUMMY" as the first argument then I receive this error
Error('An object or column name is missing or empty. For SELECT INTO statements, verify each column has a name. For other statements, look for empty alias names. Aliases defined as "" or [] are not allowed. Change the alias to a valid name. [SQLCode: 1038], [SQLState: S0004]',)
Using a profiler on the database whilst running my script shows that in the second case the following SQL is executed:
use []
go
So it would seem that when using a single string to identify the procedure, the database name is not correctly parsed out.
One of my trial and error attempts to fix this was to call callproc as follows:
cur.callproc(('CSM', '', 'dbo.DUMMY'), ['carrier1'])
This got me only as far as
Error("Procedure or function 'DUMMY' expects parameter '#carrierId', which was not supplied. [SQLCode: 201], [SQLState: S0004]",)
In this case what I think is happening is that zxJDBC attempts to call a system stored procedure (sp_proc_columns) to determine the required parameters for the stored procedure I want to call. My guess is that with the procedure identifier in the incorrect format above, zxJDBC does not get a valid/correct return and assumes no parameters are required.
So basically I am not a bit stuck for ideas as to how to get it to
Use the correct database name
Correctly determine the required parameters using sp_proc_columns
Call my stored procedure with the correct name
all at the same time.
I do have a workaround, which is to use something like
cur.execute('EXEC CSM.dbo.DUMMY ?', ['carrier1'])
However I feel like callproc() is the correct solution, and would likely produce cleaner code when I come to call stored procedures with large numbers of parameters.
If anyone can spot the mistake(s) that I am making, or knows that this is not ever going to work as I think then any input would be much appreciated.
Thanks
Edit
As suggested by i-one, I tried adding cur.execute('USE CSM') before calling my stored procedure (also removing the database name from the procedure call). This unfortunately produces the same Object or Column missing error as above. The profiler shows USE CSM being executed, followed by USE [] so it seems that callproc() always fires a USE statement before the procedure itself.
I have also experimented with turning on/off autocommit, to no avail.
Edit 2
Further information following comments/suggested solutions:
"SQLEXPRESS" in my connection string is the database instance name.
Using double quotes instead of single has no effect.
Including the database name in the connection string (via ;databaseName=CSM; as specified here) and omitting it from the callproc() call leads to the original error with a USE [] statement being fired.
Using callproc(('CSM', 'dbo', 'dbo.DUMMY'), ['carrier1']) gives me some progress but results in the error
Error("Procedure or function 'DUMMY' expects parameter '#carrierId', which was not supplied. [SQLCode: 201], [SQLState: S0004]",)
I'll attempt to investigate this further
Edit 3
Based on the queries I could see zxJDBC firing, I manually executed the following against my database:
use CSM
go
exec sp_sproc_columns_100 N'dbo.DUMMY',N'dbo',N'CSM',NULL,N'3'
go
This gave me an empty results set, which would seem to explain why zxJDBC isn't passing any parameters to the stored procedure - it doesn't think it needs to. I have yet to figure out why this is happening though.
Edit 4
To update the above, the empty result set is because the call should be
exec sp_sproc_columns_100 N'DUMMY',N'dbo',N'CSM',NULL,N'3'
This unfortunately brings me full circle as I can't remove the dbo owner from the stored procedure name in my callproc() call or the procedure won't be found at all.
Edit 5
Table definition as requested
CREATE TABLE [dbo].[carrier](
[carrierId] [varchar](50) NOT NULL,
[test] [varchar](50) NULL
) ON [PRIMARY]
Though completely unaware of the technologies used here (unless some minor knowledge of SQL Server), I will attempt an answer (please forgive me if my jython syntax is not correct. I am trying to outline possibilities here not exact code)
My first approach (found at this post) would be to try:
cur.execute("use CSM")
cur.callproc(("CSM","dbo","dbo.DUMMY"), ["carrier1"])
This must have to do with the fact that sa users always have the dbo as a default schema (described at this SO post)
If the above does not work I would also try to use the CSM database name in the JDBC url (this is very common when using JDBC for other databases) and then simply call one of the two below.
cur.callproc("DUMMY", ["carrier1"])
cur.callproc("dbo.DUMMY", ["carrier1"])
I hope this helps
Update: I quote the relevant part of the link that you can't view
>> Program calls a Stored Procedure - master.dbo.xp_fixeddrives on MS SQL Server
from com.ziclix.python.sql import zxJDBC
def getConnection():
url = "${DBServer.Url}"
user= "${DBServer.User}"
password = "${DBServer.Password}"
driver = "${DBServer.Driver}"
con = zxJDBC.connect(url, user, password, driver)
return con
try:
conn = getConnection()
print 'Connection successful'
cur = conn.cursor()
cur.execute("use master")
cur.callproc(("master", "dbo", "dbo.xp_fixeddrives"))
print cur.description
for a in cur.fetchall():
print a
finally:
cur.close()
conn.close()
print 'Connection closed'
The error you get when you specified the call function like above suggests that the parameter is not passed correctly. So please modify your stored procedure to take a default value and try to call with passing params = [None]. If you see that the call succeeds we must have done something right as far as specifying the database is concerned.
Btw: the most recent documentation suggests that you should be able to access it with your syntax.
As outlined in comments callproc will work only with SELECT. Try this approach instead:
cur.execute("exec CSM.dbo.DUMMY #Param1='" + str(Param1) + "', #carrierId=" + str(carrierID))
Please see this link for more detail.
I want to run a native SQL from a file using Hibernate. The SQL can contain several statements creating the database structure (i.e. tables, constraints but no insert/update/delete statements).
Example, very simple query is below (which contains the following two SQL statements)
CREATE DATABASE test;
CREATE TABLE test.testtbl( id int(5));
I am using MySQL db, and when I run the above query I am gettng syntax error returned. When I run them one by one, its ok.
Caused by: com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException:
You have an error in your SQL syntax; check the manual that corresponds to your
MySQL server version for the right syntax to use near
'CREATE TABLE test.testtbl( id int(5))' at line 1
The code to run the query is below (above statement is assigned to 'sql' variable):
session = sf.openSession();
session.beginTransaction();
Query qry = session.createSQLQuery(sql);
qry.executeUpdate();
session.getTransaction().commit();
Any help would be appreciated.
As others have explained
You must run these queries one by one.
The hibernate code gets translated into running one update statement on JDBC.
But you provided two update statements.
In addition,
I personally prefer to have the code that creates tables outside of the Java application, in some DB scripts.
The parameters of the method createSQLQuery is t-sql code;
t-sql code to ensure that in the mysql interface analyzer correctly.
You can try changed the sql :'CREATE TABLE testtbl(id int(5));'
by the way you can use JDBC Connection api (Don't recommend to do so)
Such as:
java.sql.Connection conn=session.connection();
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.
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