Connect Oracle Java Stored Procedure to MySQL - java

So I am building a java stored procedure on an Oracle Database 11g Enterprise Edition. I want my Java stored procedure to connect to a MySQL database, grab records and update my Oracle database. I can connect using
private Connection getConnection() throws SQLException {
// Create an OracleDataSource instance and set properties
OracleDataSource ods = new OracleDataSource();
ods.setUser(user);
ods.setPassword(passwd);
ods.setURL(url);
return ods.getConnection();
}
I am connecting using the following lib which works fine
import oracle.jdbc.pool.OracleDataSource;
But when I try to open a connection to a MySQL database in the Java stored procedure I get the following error
ORA-29532: Java call terminated by uncaught Java exception:
java.sql.SQLException: No suitable driver
ORA-06512: at "OPS.FN_JOB_UPDATE_ORACLE_LINE", line 1
ORA-06512: at "OPS.JOBS_PKG", line 13
ORA-06512: at line 2
I am assuming it has something to do the MySQL driver not being in the classpath on the Oracle server itself but I am not sure how to get it within the classpath.
Here is an example of how I am trying to connect to the MySQL database from the java stored procedure
public Connection setMysqlConnection(EntityDBSettings entity) throws
SQLException {
String connectionStr = String.format("jdbc:mysql://%s/%s?user=%s&password=%s", entity.getHost_uri(),
entity.getName(), entity.getUsername(), entity.getPaswrd());
this.connect = DriverManager.getConnection(connectionStr);
return this.connect;
}
So is it possiable to connect to a MySql database from a oracle java stored procedure? Or do I need another solution?

Related

Copying a Clob in another Clob with different implementation

In my company we are performing a database migration. For lots of reasons we cannot use a database migration tool, so we had to develop our migration tool to copy from a DB to another all rows contained in some specific tables. We have developed a tool using JDBC of multiple database. At the moment, we are migrating from DB2 to Oracle, with an intermediate step to H2. Same tables ha a Clob column. When we export this column from DB2 to H2 we get no errors or issues, but when we try to copy the Clob from H2 to Oracle using JDBC we get the following exception:
ClassCastException: cannot cast from org.h2.jdbc.JdbcClob to oracle.jdbc.Clob
Is there a way or a procedure to perform this kind of conversion? Something like a ClobCopy utility within different Clob types? Unfortunately we can do this task only using Java and Jdbc, no JPA or DB migration tools due to customer specifications.
This is an example of what I'm trying to do:
public class CopyTable {
public void doCopy(){
Connection h2 = getH2Connection(); //suppose this exists and works
Connection oracle = getOracleConnection(); //suppose this exists and works
String sqlSelect = "select * from tabletoexport";
String sqlInsert = "insert into tabletofill(ID, DATA) values (?,?)";
PreparedStatement select = h2.prepareStatement(sqlSelect);
PreparedStatement insert = oracle.prepareStatement(sqlInsert);
ResultSet rs = select.executeQuery();
while (rs.next()){
insert.setLong(1, rs.getLong("ID"));
insert.setClob(2, rs.getClob("DATA")); //this throws an exception
insert.executeUpdate();
}
}
}
The Clob interface has a getCharacterStream() method which returns a Reader, and the PreparedStatement interface has a setClob() method which takes a Reader. All you need to do to get the copy working is to use these methods.
In other words, replace the line
insert.setClob(2, rs.getClob("DATA")); //this throws an exception
with
insert.setClob(2, rs.getClob("DATA").getCharacterStream());
As for why the import from DB/2 to H2 didn't complain, perhaps the H2 JDBC driver doesn't assume that Clob values passed in to setClob come from H2, but the Oracle JDBC driver does assume that Clobs passed in in the same way are from Oracle. However, the Oracle JDBC can't reasonably make any such assumptions about a Reader, as these could come from anywhere

AbstractMethodError thrown when creating a Clob object in Java oracle procedure

I'm developing a Java PLSQL procedure that must instanciate a CLOB object. In order to instanciate that Clob object I must use a connection object. Based on Oracle documentation, I can get the current connection using java.sql.DriverManager however when I execute the following code an AbstractMethodError error is thrown
Connection conn = DriverManager.getConnection("jdbc:default:connection:");
Clob clob = conn.createClob();
I see a lot of posts talking about driver compatibility with Java runtime running the code but as I am working inside an Oracle DB I suppose it should be compatible.
Oracle version: 11.2.0.4.0
My goal is to create a clob inside my java method and return it to my plsql code. How can I instanciate a Clob inside a java class stored inside an Oracle database ?
Thanks for any help !
The creation of the CLOBusing conn.createClob() works for my fine in 12c. I suspect from your error message in 11 you'll have to use the CLOB.createTemporary method to create the CLOB (which works fine in 12c as well but is marked as deprecated).
Here an example
Java class
CREATE OR REPLACE AND RESOLVE JAVA SOURCE NAMED "CreateCLOB"
AS
import java.sql.*;
import oracle.sql.*;
import oracle.jdbc.*;
/****** START PASTE JAVA CLASS HERE *****/
public class CreateCLOB{
public static void ClobProc (Clob cl[]) throws SQLException
{
Connection conn = DriverManager.getConnection ("jdbc:default:connection:"); /* or use "jdbc:oracle:kprb:" */
Clob clob = CLOB.createTemporary(conn, false, oracle.sql.CLOB.DURATION_SESSION); /* this is deprecated in 12c */
// conn.createClob(); /* works fine in 12.1.0.2.0 */
clob.setString(1, "Test Data");
cl[0] = clob;
}
}
/
Wrapper
create or replace procedure MyClob (cl OUT Clob)
as language java
name 'CreateCLOB.ClobProc(java.sql.Clob[])';
/
Test
declare
x Clob;
begin
MyClob(x);
dbms_output.put_line('created CLOB length = ' || dbms_lob.getlength(x));
end;
/
created CLOB length = 9
As mentioned I can't test it on version 11, but I suppose it will work.
select * from v$version;
Oracle Database 12c Enterprise Edition Release 12.1.0.2.0 - 64bit Production
You need to follow these steps:
1. On your computer you should have an Oracle jdbc driver (http://www.oracle.com/technetwork/database/features/jdbc/index-091264.html)
2. Load a driver
Class.forName("oracle.jdbc.driver.OracleDriver");
3. Get a connection
Connection connection =
DriverManager.getConnection("jdbc:oracle:thin:#localhost:1521:SID","username","password");
UPDATE: If you work inside of Oracle DB, you can choose a type of driver (Server-Side Thin Driver or Server-Side Internal Driver) - https://docs.oracle.com/cd/E11882_01/appdev.112/e13995/oracle/jdbc/OracleDriver.html
Even when you are not using the createClob() you may get this error when starting the application if you are using an older version of hibernate core library.
The errors is just thrown, but the application starts. If you are not worried about it you may leave it, but if you don't want to see an error during application startup then her is the fix.
Its a bug in the Spring boot 2.X - hibernate core 5.3.X combination. There are 2 solutions for the issue. I would suggest #1.
Upgrade all hibernate libraries to 5.4.X (my way)
Provide spring.jpa.properties.hibernate.jdbc.lob.non_contextual_creation=true in your application properties/ yml file.(If you really do not want to upgrade your hibernate core library).
I have got this when upgrading spring boot to 2.4 and using Teradata DB without any createClob().
If you still want to know how the error is being created, its well explained in https://alexpask.com/spring-boot-createclob-error/

Teradata external Java Stored Procedure error: No suitable driver found for jdbc:default:connection

I wrote a Java stored procedure, packed it into a jar and installed it into the Teradata database. I want to use the default database connection as described here. Most of the code was generated by the Teradata wizard for stored procedures.
public class TestSql {
public static void getEntryById(int id, String[] resultStrings) throws SQLException {
Connection con = DriverManager.getConnection("jdbc:default:connection");
String sql = "SELECT x FROM TEST_TABLE WHERE ID = " + id + ";";
Statement stmt = (Statement) con.createStatement();
ResultSet rs1 = ((java.sql.Statement) stmt).executeQuery(sql);
rs1.next();
String resultString = rs1.getString(1);
stmt.close();
con.close();
resultStrings[0] = resultString;
}
}
I installed the jar:
CALL SQLJ.REPLACE_JAR('CJ!/my/path/Teradata-SqlTest.jar','test');
And created the procedure:
REPLACE PROCEDURE "db"."getEntryById" (
IN "id" INTEGER,
OUT "resultString" VARCHAR(1024))
LANGUAGE JAVA
MODIFIES SQL DATA
PARAMETER STYLE JAVA
EXTERNAL NAME 'test:my.package.TestSql.getEntryById(int,java.lang.String[])';
Now when I call this procedure, I get this error message:
Executed as Single statement. Failed [7827 : 39001] Java SQL Exception SQLSTATE 39001: Invalid SQL state (08001: No suitable driver found for jdbc:default:connection).
Now when I log off from Teradata and log on again and call the procedure, the error message becomes:
Executed as Single statement. Failed [7827 : 39001] A default connection for a Java Stored Procedure has not been established for this thread.).
What is the problem here? I'm connecting to Teradata using the Eclipse plugin. Teradata v. 15.0.1.01.
After many hours I finally found the problem. Eclipse packed all dependencies into the jar - which basically is ok. However it also packed the Teradata JDBC driver files (tdgssconfig.jar and terajdbc4.jar) into the result jar, which was the problem.
I adjusted the jar building process so that these files are not included and the errors went away.

How to connect to remote database through DB link using JDBC?

I need to connect to a remote database using Database link using JDBC commands.
How can it be done?
If you already have the dblink setup, you can utilize it in your SQL (sent via jdbc) by addressing the required tables like such:
select * from SCHEMA.TABLE#DBLINK_NAME
Using this query inside of your java would look something like this
public ResultSet execQuery() throws SQLException, ClassNotFoundException{
//Load the database driver
Class.forName("oracle.jdbc.OracleDriver");
//Create connection to the database
Connection myConnection = DriverManager.getConnection(connectURL,userName,userPwd);
//Create a statement link to the database for running queries
Statement myQuery = myConnection.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE,ResultSet.CONCUR_UPDATABLE);
//Create a resultSet to hold the returned query information
ResultSet myQueryResults = myQuery.executeQuery("select * from SCHEMA.TABLE#DBLINK_NAME");
return myQueryResults;
}
*java & oracle assumed
If you are asking about how to use JDBC to create a link between the DB you are talking to and another one, then it is "just SQL" that you (presumably) would execute in the same way as you would any other SQL statement. (If you tell us which DB you are using, we could talk about the actual SQL you need to execute.)
Otherwise, I don't think this makes sense. A DB link / Database link is a link from one database to another. But JDBC is for talking to a database from a Java client. It makes no sense (to me) to use DB link to connect a JDBC client to a database.
Please take a look at orajdbclink, on sourceforge
I am planning to to connect my oracle plsql sources to phoenix skin of hbase. It seems to me the unique way to create a connector between oracle and hbase for the moment...

How to Create a MySql Database using JDBC

Can we create a new MySQL database( not a table, I want a new database) from java code ? I have searched the internet and I get code only for connecting with existing mysql databases. Can i create a new database at run time using java code.
please help
In your connection string omit a database name and then execute Create database command.
Connection String: jdbc:mysql://localhost
Create Database Syntax : stm.executeUpdate("CREATE DATABASE dbname")
Class.forName("org.gjt.mm.mysql.Driver").newInstance();
String url ="jdbc:mysql://localhost/myDB?user=soft&password=soft1234&useUnicode=true&characterEncoding=8859_1";
Connection conn = DriverManager.getConnection(url);

Categories