Running PL/SQL and T-SQL Through JDBC - java

I'm wondering what's the best way to run a PL/SQL or T-SQL code blocks through JDBC.
To be more specific - what JDBC API should one use to execute PL/SQL or T-SQL blocks that return ResultSets?
Update:
Even more specifically - I have a generic code that receives SQL code (may be SQL, PL/SQL or T-SQL) as an input, loads the appropriate JDBC driver according to the required database, and executes the given SQL code as follows:
Statement stmt = conn.createStatement ();
ResultSet rs = stmt.executeQuery("BEGIN some code END SELECT * FROM MY_TABLE");
while (rs.next ()) {
System.out.println (rset.getString (1));
}
This returns no ResultSet when using some T-SQL or PL/SQL objects like cursors for example.
And so, I was wondering if this JDBC API is the best way to execute such queries. In case it is, then there must be a bug in the specific JDBC driver implementation i'm using.

A CallableStatement is generally the way to go. This link gives an example how to do it in Oracle:
Using Cursor Variables
Note that you get a Cursor, not a ResultSet.
In T-SQL (which I don't know well) a CallableStatement with executeQuery should work as expected, see this link:
JDBC: CallableStatement

You need to provide the connection information beforehand to execute the SQL. You cannot infer the database from the SQL. So I don't think there is any such API which is present to handle such queries.
You can use the standard JDBC API. An example from here:
import java.sql.*;
import oracle.jdbc.pool.OracleDataSource;
class JdbcTest {
public static void main (String args []) throws SQLException {
// Create DataSource and connect to the local database
OracleDataSource ods = new OracleDataSource();
ods.setURL("jdbc:oracle:thin:#//myhost:1521/orcl");
ods.setUser("scott");
ods.setPassword("tiger");
Connection conn = ods.getConnection();
// Query the employee names
Statement stmt = conn.createStatement ();
ResultSet rset = stmt.executeQuery ("SELECT ename FROM emp");
// Print the name out
while (rset.next ())
System.out.println (rset.getString (1));
//close the result set, statement, and the connection
rset.close();
stmt.close();
conn.close();
}
}

Related

When I run SQL query from RIDE it gives error

I am having this problem,
When I send an SQL query as an argument it gives error
when I use the same query directly in my java program it works fine.
MY SQL query when I send as an argument is as follow
Select RATINGPERIOD from INVESTMENT.I1INVE Where INVESTMENTID = 100
rs = stmt.executeQuery(sqlQery); // Select RATINGPERIOD from INVESTMENT.I1INVE Where INVESTMENTID = 100
and when I use it directly into my java program is as follow
try
{
// Load the driver
Class.forName("com.ibm.db2.jcc.DB2Driver");
System.out.println("**** Loaded the JDBC driver");
// Create the connection using the IBM Data Server Driver for JDBC and SQLJ
con = DriverManager.getConnection (url, user, password);
// Create the Statement
stmt = con.createStatement();
System.out.println("**** Created JDBC Statement object");
// Execute a query and generate a ResultSet instance
rs = stmt.executeQuery("Select RATINGPERIOD from INVESTMENT.I1INVE where INVESTMENTID = 100");
while (rs.next()) {
delay = rs.getString("RATINGPERIOD");
System.out.println("size of list ="+delay);
}
}
Error log
com.ibm.db2.jcc.am.SqlException: [jcc][10103][10941][3.62.57] Method executeQuery cannot be used for update. ERRORCODE=-4476, SQLSTATE=null
at com.ibm.db2.jcc.am.fd.a(fd.java:660)
at com.ibm.db2.jcc.am.fd.a(fd.java:60)
at com.ibm.db2.jcc.am.fd.a(fd.java:120)
at com.ibm.db2.jcc.am.jn.a(jn.java:4129)
at com.ibm.db2.jcc.am.jn.a(jn.java:2875)
at com.ibm.db2.jcc.am.jn.a(jn.java:679)
at com.ibm.db2.jcc.am.jn.executeQuery(jn.java:663)
at com.profitsoftware.testing.utils.keywords.date.DatabaseSQL.sqlQuery(DatabaseSQL.java:46)
at com.profitsoftware.testing.utils.keywords.date.DatabaseSQLKeywords.executeSqlQuery(DatabaseSQLKeywords.java:18)com.
ok some more information, I have assigned sql query to a string in Java program and then compared it to the query(String) I was getting as argument in my java program and it gives false. which explain maybe when query is passed from RIDE to Java programm it changes somehow. any idea what happens there ?
Thanks in advance and sorry if it sounds a stupid question, I a new to this programming world.
oK, It started to work, actually I was missing something there, so type. My logic itself was good but it was typo that created the problem
--Sara

Execute a PL/SQL procedure using Java code

I would like to execute PL/SQL procedure using Java code. I've tried this so far :
Statement myStmt = null;
myStmt = conn.createStatement();
myStmt.executeQuery("EXECUTE ProjetIRSTEA.detectionX");
And I get the following error message:
java.sql.SQLSyntaxErrorException: ORA-00900: invalid SQL statement
You have to use the CallableStatement class to execute Stored Procedures.
Please, check this sample published by Oracle to see how to use this class:
https://docs.oracle.com/cd/A84870_01/doc/java.816/a81354/samapp2.htm
Try:
myStmt.executeUpdate("BEGIN ProjetIRSTEA.detectionX; END");
You can also use a method of calling stored procedures defined by the JDBC standard, using CallableStatement Interface:
CallableStatement myCall = connection.prepareCall("{call ProjetIRSTEA.detectionX()}")
myCall.executeUpdate();
On Oracle, you can use either a CallableStatement (as explained above) or just issue a normal sql query using a Statement or PreparedStatement (the former method is preferred though) .
String sql = " select ProjetIRSTEA.detectionX() from dual";
PreparedStatement stmt = conn.prepareStatement(sql);
stmt.execute();
Note that you have to reference the system table dual in your select statement.

SQL statement - NullPointerException

I have been assigned a task at work but i'm a beginner in Java and Eclipse.
I have to re-use an existing programm and modify some parts of it.
The following part does'nt work:
private java.sql.Connection conn;
private final String sqlRequest = "select ... from ...";
//................
private void DBConnect(){
try {
// Load the driver
java.lang.Class.forName(jdbcdriver).newInstance();
// Connect to database
conn = java.sql.DriverManager.getConnection(jdbcURL,dbuser,dbpwd);
//................
private void search2() {
try {
// create SQL statement
java.sql.Statement stmt = conn.createStatement(); //my line 135
java.sql.ResultSet rs = execRequest(stmt,sqlRequest);
//................
The error message in eclipse is :
"java.lang.NullPointerException at mon_prog.search2(mon_prog.java:135)"
This part used to work before... so is the problem due to my JDK version? I have JDK7u2
Get the connection first ...using..
Connection conn = DriverManager.getConnection(connection string);
Your conn seems null.
Have a look into great Vogella tutorial on how to connect to MySQL database from java program (IDE neutral way): http://www.vogella.de/articles/MySQLJava/article.html
Example steps to connect to your database:
// This will load the MySQL driver, each DB has its own driver
Class.forName("com.mysql.jdbc.Driver");
// Setup the connection with the DB
connect = DriverManager
.getConnection("jdbc:mysql://localhost/feedback?"
+ "user=sqluser&password=sqluserpw");
// Statements allow to issue SQL queries to the database
statement = connect.createStatement();
// Result set get the result of the SQL query
resultSet = statement
.executeQuery("select * from FEEDBACK.COMMENTS");
Set breakpoints on the Class.forName() and getConnection() calls in DBConnect(), and on your line 135, then run it all through the debugger. I wouldn't be the least bit surprised if getConnection() doesn't get executed before you try to use the connection. (Been there, done that, got the source control commit.)
If that's not it, you may also want to double-check that you really don't have another variable that is shadowing your intended conn instance. "Go to definition" is very useful for this; just make sure you end up in the expected place.

Creating a "Java DB" database and associated tables in main checking to see if they exist?

I'm creating an applicaation on Netbeans 7! I'd like my application to have a little code in main so that it can create a Java DB connection checking to see if the database and the associate tables exist, if not create the database and the tables in it. If you could provide a sample code, it'd be just as great! I have already looked at http://java.sun.com/developer/technicalArticles/J2SE/Desktop/javadb/ but I'm still not sure how to check for an existing database before creating it!
I'd like my application to have a little code in main so that it can create a Java DB connection checking to see if the database and the associate tables exist, if not create the database and the tables in it.
You can add the create=true property, in the JDBC URL. This creates a Derby database instance if the database specified by the databaseName does not exist at the time of connection. A warning is issued if the database already exists, but as far as I know, no SQLException will be thrown.
As far as creation of the tables is concerned, this is best done on application startup before you access the database for typical transactional activity. You will need to query the SYSTABLES system table in Derby/JavaDB to ascertain whether your tables exist.
Connection conn;
try
{
String[] tableNames = {"tableA", "tableB"};
String[] createTableStmts = ... // read the CREATE TABLE SQL statements from a file into this String array. First statement is for the tableA, and so on.
conn = DriverManager.getConnection("jdbc:derby:sampleDB;create=true");
for(int ctr =0 ; ctr < tableNames.length; ctr++)
{
PreparedStatement pStmt = conn.prepareStatement("SELECT t.tablename FROM sys.systables t WHERE t.tablename = ?");
pStmt.setString(1, tableNames[ctr]);
ResultSet rs = pStmt.executeQuery();
if(!rs.next())
{
// Create the table
Statement stmt = conn.createStatement();
stmt.executeUpdate(createTableStmts[ctr]);
stmt.close();
}
rs.close();
pStmt.close();
}
}
catch (SQLException e)
{
throw new RuntimeException("Problem starting the app...", e);
}
Any non-existent tables may then be created. This is of course, not a good practice, if your application has multiple versions, and the schema varies from one version of the application to another. If you must handle such a scenario, you should store the version of the application in a distinct table (that will usually not change across versions), and then apply database delta scripts specific to the newer version, to migrate your database from the older version. Using database change management tools like DbDeploy or LiquiBase is recommended. Under the hood, the tools perform the same operation by storing the version number of the application in a table, and execute delta scripts having versions greater than the one in the database.
On a final note, there is no significant difference between JavaDB and Apache Derby.
I don't know how much Oracle changed Derby before rebranding it, but if they didn't change too much then you might be helped by Delete all tables in Derby DB. The answers to that question list several ways to check what tables exist within a database.
You will specify the database when you create your DB connection; otherwise the connection will not be created successfully. (The exact syntax of this is up to how you are connecting to your db, but the logic of it is the same as in shree's answer.)
The create=true property will create a new database if it is not exists. You may use DatabaseMetadata.getTables() method to check the existence of Tables.
Connection cn=DriverManager.getConnection("jdbc:derby://localhost:1527/testdb3;create=true", "testdb3", "testdb3");
ResultSet mrs=cn.getMetaData().getTables(null, null, null, new String[]{"TABLE"});
while(mrs.next())
{
if(!"EMP".equals(mrs.getString("TABLE_NAME")))
{
Statement st=cn.createStatement();
st.executeUpdate("create table emp (eno int primary key, ename varchar(30))");
st.close();;
}
}
mrs.close();
cn.close();
Connection conn = getMySqlConnection();
System.out.println("Got Connection.");
Statement st = conn.createStatement();
String tableName = ur table name ;
String query = ur query;
Statement stmt = null;
ResultSet rs = null;
try {
stmt = conn.createStatement();
rs = stmt.executeQuery(query);
System.out.println("Exist");;
}
catch (Exception e ) {
// table does not exist or some other problem
//e.printStackTrace();
System.out.println("Not Exist");
}
st.close();
conn.close();

What is the best way/template to set up connection mysql and jdbc?

What is the best way to set up connection with mysql's jdbc?
And execute simple statement. How to do that?
Thank you.
The basic boilerplate for MySQL/JDBC goes something like this:
Get the connection:
Class.forName("com.mysql.jdbc.Driver").newInstance();
Connection conn = DriverManager.getConnection("jdbc:mysql://databaseName");
Execute the statement:
Statement stmt = conn.createStatement();
ResultSet rs = stmt.executeQuery("SELECT * from tableName");
while (rs.next()) {
System.out.println(rs.getString(1));
}
Close the statement and connection:
rs.close();
stmt.close();
conn.close();
You just need to make sure you have the driver installed and/or in your CLASSPATH.
This is the twenty first century - use a JPA (ORM) implementation. But if you insist on going back to the metal (at the risk of down votes) -
There are many ways of getting a JDBC connection from some driver. Using reflection with a hardwired class name is the commonest and perhaps most brain damaged. If you're going to hardwire a class name, you might as well as get the benefits of normal code (compiler catches typos, no extraneous exceptions to deal with, easier to read, explicit dependencies, better tool support, etc).
Also get in to the habit of clearing up resources safely.
So:
public static void main(String[] args) throws SQLException {
Driver driver = new com.mysql.jdbc.Driver();
Connection connection = driver.connect(
"jdbc:mysql://mydatabase",
new java.util.Properties() {{
put("user", "fred");
}}
);
try {
PreparedStatement statement = connection.prepareStatement(
"SELECT insideLeg FROM user WHERE name=?"
);
try {
statement.setString(1, "jim");
ResultSet results = statement.executeQuery();
try {
if (results.next() {
System.out.println("= "+results.getLong(1));
} else {
System.out.println("Missing.");
}
} finally {
results.close();
}
} finally {
statement.close();
}
} finally {
connection.close();
}
}
What a mess! And it doesn't even use transactions yet. Yes, use an ORM. They're very respectable these days.
You wont need to do all that for every single statement. You don't want to go around creating instantiating drivers every time. In particular the execute around idiom is useful.
It depends on your case.
If you simply need to execute some queries from standalone application then you should use single connection like:
Class.forName ("yourDriverName");
Connection cn = DriverManager.getConnection ("db url");
Statement st = cn.createStatement ();
ResultSet rs = st.executeQuery ("select * from foo");
while (rs.next()) {
doSmth ();
}
rs.close ();
st.close ();
cn.close ();
But if you are developing real application (specially web-application) then use DataSource's. Read manual of your DB and Web-server how to configure datasource. DataSource allows you to use connection-pooling - it'll nessecary to increase performance.
Configuring DataSource isn't difficult process.
Here's the sun documentation for creating a JDBC connection. From there it's easy to get access to a Statement object and run some simple SQL.
For production level systems you'll probably also want to create a connection pool.
Use Spring Framework's JDBC abstraction framework - all you need to do is create a context XML file, and use the JDBC template class. Just a few lines of XML + Java code will get you going. The advantage is keeping your connection details out of compiled Java. See:
http://www.springbyexample.org/examples/simple-spring-jdbc-template.html

Categories