Procedure in DB not working when called from Java - java

I have an Java application running on a Weblogic Server and Connecting to Oracle 11g DB server.
In the application i make a call to a DB Procedure and pass a parameter to it which communicates and calls multiple other procedures.
When i test the Procedure independently, it works perfectly and as expected.
The issue comes when i call the Procedure from Java Application.
The Procedure gives an error:
ORA-06508: PL/SQL: could not find program unit being called
The Backtrace leads to a call to a procedure that exists in another Schema and has a synonym in my current schema.
Please help if anybody else has faced the same issue or a similar one.
Edit#1:
Sample Code for Calling DB Proc
CallableStatement cstmt = null;
private Connection dbConn = null;
HashMap hashMap = new HashMap();
hashMap.put(DBDRIVER, driverType);
hashMap.put(USERID, userName);
hashMap.put(PASSWORD, password);
hashMap.put(SID, dbName);
hashMap.put(IPADDRESS, intDBServer);
hashMap.put(PORT, dbPort);
dbConn = (Connection)cmmObj.connect(hashMap);
cstmt = dbConn.prepareCall(queryToRun);
cstmt.setString(1, ReqId);
cstmt.executeUpdate();
Proc Call is { call Proc_CALL(?) }

It sounds to me as though your synonym is the wrong way round - the calling schema needs a synonym for the called procedure + permissions to execute.

I have probably found the issue. Although it seams weird to hear it but it seems to work:
The system i was working on has 3 Schema in connection.
One is the Staging Schema from which all the calls are made.
Second is the Main Schema to which calls were made. The Called Procedure existed in this Schema.
The third is another schema where a procedure existed that was being called from Main Schema Procedure.
Simplified:
StageSchema.Caller(Synonym)-->>
MainSchema.Proc_Call(Procedure)-->>
CoSchema.insideCall(Procedure).
The Grants to the CoSchema were available to the Main Schema, but not to the Stage Schema.
Although as per theory if Any Procedure is being granted to a schema then all inside calls to any other procedures should not matter.
but in this case when i gave the grant to Stage Schema, then everything seemed to work perfectly.
If any one has a solution to this then please share the reason for the same.

Related

Error or wrong type of code while creating connection & execute SQL query statements using mysql in java

I'm using MySQL 5.7 with Java in Eclipse, and the connection statement below code below is causing an error when I try to connect:
try
{
//1. Get a connection to database
jdbc:mysql://localhost:3306/databaseName?autoReconnect=true;useSSL=false;
// 2. Create a statement
Statement myStmt=myConn.createStatement();
// 3. Execute SQL query
ResultSet myRs=myStmt.executeQuery("select * from employee");
//4. Process the result set
while(myRs.next())
{
System.out.println(myRs.getString("last_name")+","+myRs.getString("first_name"));
}
}
catch(Exception exc){
exc.printStackTrace();
}
First things first.
Code will only be used to validate the error. So you must paste the error fired by your program.
Since we don't have enough information to the problem, I will just cover basic troubleshooting.
Basic trouble shooting:
Do you have the driver? if not, you can download it here.
Next, Do you have the driver on your project class path? If not yet, you must add it. see how here
Did you load the driver to the program? if not, Class.forName("com.mysql.jdbc.Driver"); // Load Driver like that before doing anything.
Did you establish the connection? if not, Connection con = DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/DATABASE","USERNAME","PASSWORD");//3306 or port number depends on you config, same with DATABASE, USERNAME, PASSWORD
After the connection were established, so you should create a statement object like Statement s = con.createStatement(); // Create Statement. This will be used to execute sql commands.
finally, you can execute the commands like s.execute("select * from employee"); // Execute Query NOTE that s here is the variable created on number 5.
If all of the above were properly done but still gets an error, check if your have the database server running. In you case, mysql. Make sure there were not other installation of mysql prior to your current mysql. Sometimes, it will mess up your database. Troubleshooting your mysql, see mysql official doc here
While possible error is the datatype of mysql to your java code or getting a column that does not exist on your query or worse the column does not exist on your table.
Hope that help you and other who needs it.

What is the SQL equivalent of CallableStatement?

I have some code I'm trying to fix and a function is used within a CallableStatement but it seems that said function is called in a particular instance where a Schema of the Database becomes the entire 'see-able' database for the function.
Let me explain :
My database (in PostgreSQL) has multiple projects (schemas) such as i2b2test_project or i2b2test_project2. Each of these projects has an architecture of multiple tables, such as visit_dimension, patient_dimension, etc..
Now, if I want to reference the visit_dimension table from a i2b2test_project, I need to use i2b2test_project.visit_dimension, as any logical SQL syntax would suggest.
The problem is that, in the code (which I'll include below), a CallableStatement is used to execute a function (plain old load-table-from-temp-table function). This function references the architecture mentioned above as if only one project exists, as the database. In other words, instead of referencing i2b2test_project.visit_dimension, it only references visit_dimension.
I haven't found a way to execute a function in some sort of 'separated instance' of the database and as a result, the function can not be used in a plain SQL statement inside a DB terminal, errors such as visit_dimension table does not exist etc..
So I ask : Does the call statement (which indeed seems to reference the schema) allow for such a 'separated instance' of the database ? And is there a way to do so with a plain SQL statement ?
Code :
CallableStatement callStmt = conn.prepareCall("{call "
+ this.getDbSchemaName()
+ "INSERT_ENCOUNTERVISIT_FROMTEMP(?,?,?)}");
callStmt.setString(1, tempTableName);
callStmt.setInt(2, uploadId);
callStmt.registerOutParameter(3, java.sql.Types.VARCHAR);
callStmt.execute();

Invoking stored procedure from other schema to create tables

I am working on the web application project developed using java. In my working project,
i have the requirement like i need to create the database dynamically after the user has been registered.I had done that approach.
But, now i want to call one stored procedure that is available in another schema(Master DB).The stored procedures contains tables. Now, i want to call that procedure in dynamically created DB.
I have written the code like following, can anybody help me to know what's wrong in this code,
Connection c1 = DriverManager.getConnection(URL, USER, PASSWORD);
java.sql.CallableStatement cstmt=null;
System.out.println("Invoking the stored procedure from subscription DB........");
String callSP="{call masterdb.createCorporateDBProc()};";
cstmt= c1.prepareCall(callSP);
cstmt.execute();
java.sql.CallableStatement cstmt=null;
try {
System.out.println("Invoking the stored procedure from subscription DB........");
String callSP="{call subscription.createCorporateDBProc()}";
cstmt = c1.prepareCall(callSP);
int r = cstmt.executeUpdate();
System.out.println("SP created"+r);
System.out.println("SP invoked and executed successfully in corporate DB....");
} catch(com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException e){
e.printStackTrace();
cstmt.close();
c1.close();
}
See javadoc for Statement:
http://docs.oracle.com/javase/7/docs/api/java/sql/Statement.html#executeUpdate%28java.lang.String%29
Returns:
either (1) the row count for SQL Data Manipulation Language (DML) statements or (2) 0 for SQL statements that return nothing
This means that execute for procedure will return 0. Check your database as well, if the call was successful.

INSERT failed because the following SET options have incorrect settings: 'ARITHABORT'

I have read the topics in Stackoverflow about this problem, but I really haven't a solution yet.
My problem is sending a String or Clob as an XML parameter in a Stored Procedure in SQL Server 2008. I'm using jTDS to connect it. I've read that I have to set the "ARITHABORT" to ON, but I really don't know where I can do it.
Maybe in my own session in JAVA or in DB too... Please help!! (And sorry for my very very bad english)
Ok! Here is the method that is giving me the error:
private static final String PR_SV_MUDA_STATUS_EVENTO_CONCLUIDO = "{CALL PR_SV_MUDA_STATUS_EVENTO_CONCLUIDO(?, ?, ?, ?)}";
public String modificaStatus(Connection connection, Integer eventoRobo, String path) throws SQLException {
Connection conn = null;
conn = GenericHibernateDAO.criaConexao();
CallableStatement cs2 = conn.prepareCall(PR_SV_MUDA_STATUS_EVENTO_CONCLUIDO);
cs2.setInt(1, eventoRobo);
cs2.setString(2, null);
cs2.setString(3, null);
cs2.setString(4, path);
cs2.execute();
conn.close();
return null;
}
I believe this is the query
SET ARITHABORT ON;
This needs to be run before your stored procedure. Either you can run it soon after getting the connection.
Once the processing is done, you may want to run the query below.
SET ARITHABORT OFF;
These queries can be run using additional statements in your java program.
I ran into this problem today and got it solved. I created a filtered index on a column in sql server 2008 r2, but would get this error when inserting. Saw this question wasn't completely answered since it might be tedious to always turn arithabort on in every insert. I found a blog that showed it was the database compatibility level that was the issue. Changed the compatibility level from 80 (2000) to 100 (2008) and the issue was solved. not sure if changing the compatibility level to 90 would solve this or not, but worth a try.
SQL Server compatibility levels and command to change here. http://msdn.microsoft.com/en-us/library/bb510680.aspx
If this doesn't work or you can't change the compatibility mode there is another workaround by adding a trigger in the blog I was talking about here http://chrismay.org/2013/05/23/interesting-problem-with-sql-server-arithabort-filtered-indexes-calculated-columns-and-compatibility-mode-of-80/
Note that this change was done on a test database, and all applications should be tested before making a change like this in production. Make sure this is ok with your DBA before changing too.

Delete Stored Procedure through remote

I am creating and testing a stored procedure through remote using JUnit , my user name is test and this is my code,
String sql = "create procedure test.firstProc3 AS select GETDATE()";
cursor.execute(sql);
cursor.executeQuery("firstProc3");
ANd to drop the procedure:
String dropSQL = "DROP PROCEDURE test.firstProc3";
cursor.execute(dropSQL);
Since the Drop Procedure is not working, I am unable to run the same SP for the second time ( new session) My error is:
There is already an object named 'firstProc3' in the database.
When I gave sp_help on the server side,
the table had the row with the value
firstProc3 test stored procedure
However when I give
DROP PROCEDURE test.firstProc3 in the Query analyzer, the row is getting deleted from the table.
What could be the issue in trying to do the same operation through Junit?
Are there any permissions to be set?
PS - the user test has the db_ddladmin enabled.
I managed to finally solve the problem by using the following :
declare #object_id int
select #object_id = object_id('test.firstProc5')
EXEC sp_MSdrop_object #object_id
GO
This is removing the data from the table too.And I am able to successfully run the Testcase multiple times !
Thanks for your help :)
The link I referred to is here, hope it helps someone:
http://www.mssqlcity.com/Articles/Undoc/SQL2000UndocSP.htm
Based upon the error message, I doubt it is a permissions issue. It looks like your cursor object is running the create again when you're trying to drop, or you're never really dropping the proc before running your unit test again, or the tests are running out of logical order in some fashion. Can you instantiate a new cursor object and try the drop with that, or verify the SQL being run against the database using profiler or some debug output?
Beyond that, I would be curious to see if changing your SQL commands to check for proc existence makes the error go away (not that this is the right answer):
if object_id('test.firstProc3') is null begin
-- Dynamic SQL because create must be first in a batch
exec ('create procedure test.firstProc3 as select getdate()')
end
if object_id('test.firstProc3') is not null begin
drop procedure test.firstProc3
end
Maybe something small, and maybe it is even not the case, but have you tried to use escaping in your drop statement?
something like
drop procedure [test].[firstProc3]
I can remember that i had an issue with this when i called a drop table from c# code...

Categories

Resources