can anyone please help me on this? I am trying to execute a SQL query (to Microsoft SQL) using JAVA. But, nothing happens on my table. Also, no exception either. But i am pretty sure that this code directly connecting to my DB. Here's my code.
package Testing;
//import java.sql.*;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
public class TestingClass {
public static void main(String[] srg)
{
String driverName = "com.microsoft.sqlserver.jdbc.SQLServerDriver"; // Start JDBC
String dbURL = "jdbc:sqlserver://localhost:1433;DatabaseName=OPERATIONS"; // Connect the server and the database
String userName="AppControlTeam";
String userPwd="*****";
//
Connection connection = null;
try{
Class.forName(driverName);
connection = DriverManager.getConnection(dbURL,userName,userPwd);
String sql = "DELETE FROM GFR_GROWTH_RATE";
PreparedStatement statement = connection.prepareStatement(sql);
statement.executeUpdate();
connection.close();
}
catch (Exception e){
e.printStackTrace();
}
}
}
I have been already added the JDBC driver on the package. Also, i'm pretty sure that this is not a classpath issue since the connection to DB thru this code is already success.
Thanks in advance to someone who can help! :D
-Jiro
Your DELETE may be rolled back if you didn't set your JDBC driver's autocommit property to true. Maybe try calling
connection.commit();
// right before...
connection.close();
Or alternatively:
connection.setAutoCommit(true);
// before...
PreparedStatement statement = connection.prepareStatement(sql);
Probably the row is locked by a different session, may be an uncommitted session that has modified (deleted/updated) the records from the table. Another possibility is by a tool which open the row/record with locked state - so the delete statement hangs.
Related
I try to create a connection between JDBC and MS Access.
I follow the instruction as per this link. I am using IntelliJ Idea. Here I am sharing some snaps to describe my problem.
This is the code that I write down to make a connection with Database Database2. But as you can see there is no error neither any output. Now I am sharing the table structure and content on the table.
2nd picture is
My code is:
import java.sql.*;
public class Connection_sample {
public static void main(String[] args) {
try {
Class.forName("net.ucanaccess.jdbc.UcanaccessDriver");
Connection conn= DriverManager.getConnection("jdbc:ucanaccess://D://tutorial/Database2.accdb");
Statement s = conn.createStatement();
s.executeQuery("select * from Student");
ResultSet rset = s.getResultSet();
while (rset.next()) {
System.out.println(rset.getInt(1)+""+rset.getInt(2));
}
} catch (SQLException | ClassNotFoundException e) {
e.printStackTrace();
}
}
}
Can anyone help me to find the error?
Your problem is the result of using getResultSet() instead of using the result set returned by executeQuery(). You should only use getResultSet() in combination with execute().
A result set should only be obtained once, and it was already returned from executeQuery (which you ignored). When you called getResultSet, you - apparently - got an empty one (which technically violates the contract).
I have a sample code, which creates a table, inserts some rows in it and then tries to cancel the whole transaction, but conn.rollback() seems to have effect only on INSERT statements while CREATE TABLE keeps unaffected: a newly created table remains permanent in the database with no rows inserted in it.
Is this a standard behavior while using JDBC driver with MySQL DBMS?
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.Statement;
public class TestBatch {
public static void main(String[] args) {
try (Connection conn = DriverManager.getConnection(
"jdbc:mysql://localhost:3306/testdb?serverTimezone=UTC",
"root", "root")) {
// drop table
try (Statement dropStatement = conn.createStatement()) {
dropStatement.executeUpdate("DROP TABLE IF EXISTS mytable");
}
// create table, insert rows and rollback
conn.setAutoCommit(false);
try (Statement stmt = conn.createStatement()) {
stmt.addBatch("CREATE TABLE mytable (id INT)");
stmt.addBatch("INSERT INTO mytable VALUES (1)");
stmt.addBatch("INSERT INTO mytable VALUES (2)");
stmt.executeBatch();
conn.rollback();
} finally {
conn.setAutoCommit(true);
}
} catch (SQLException e) {
System.err.println(e.getMessage());
}
}
}
Please, note, I'm using MySQL Server 8.0 with Connector/J ver. 8.0.17, also the parameter default-storage-engine (in C:\ProgramData\MySQL\MySQL Server 8.0\my.ini) is set to INNODB.
As Paul Spiegel and Arnaud said, DDL statements cannot be rolled back in MySQL. This is true even for MySQL 8: https://dev.mysql.com/doc/refman/8.0/en/implicit-commit.html
For better or worse, DDL statements commit any pending transactions, if they are local and cannot be used in XA transactions (because that would cause one participant to commit data without the transaction coordinator issuing the command to do so).
I have been trying to figure out how to get SQLite working on eclipse juno. I have been following the instructions on this site http://wiki.eclipse.org/Connecting_to_SQLite. The problem is not every step is exactly as explained so I am guessing on weather I got it right or not. I feel that I have probably gotten it all correct until step 13, there is no SQL Model-JDBC Connection entry. So I have tried step 13-16 with a generic JDBC and with one that says SQLite. The SQLite one does not have a driver which is no surprise due to step 5. Any way that I have tried so far ends up failing ping with details listed below. Someone must have a better way through this process.
java.sql.SQLException: java.lang.UnsatisfiedLinkError: SQLite.Database.open(Ljava/lang/String;I)V
at SQLite.JDBCDriver.connect(JDBCDriver.java:68)
at org.eclipse.datatools.connectivity.drivers.jdbc.JDBCConnection.createConnection(JDBCConnection.java:328)
at org.eclipse.datatools.connectivity.DriverConnectionBase.internalCreateConnection(DriverConnectionBase.java:105)
at org.eclipse.datatools.connectivity.DriverConnectionBase.open(DriverConnectionBase.java:54)
at org.eclipse.datatools.connectivity.drivers.jdbc.JDBCConnection.open(JDBCConnection.java:96)
at org.eclipse.datatools.connectivity.drivers.jdbc.JDBCConnectionFactory.createConnection(JDBCConnectionFactory.java:53)
at org.eclipse.datatools.connectivity.internal.ConnectionFactoryProvider.createConnection(ConnectionFactoryProvider.java:83)
at org.eclipse.datatools.connectivity.internal.ConnectionProfile.createConnection(ConnectionProfile.java:359)
at org.eclipse.datatools.connectivity.ui.PingJob.createTestConnection(PingJob.java:76)
at org.eclipse.datatools.connectivity.ui.PingJob.run(PingJob.java:59)
at org.eclipse.core.internal.jobs.Worker.run(Worker.java:53)
Make sure you get the driver from https://bitbucket.org/xerial/sqlite-jdbc/downloads, then import the driver into your project.
Now you can test the configuration by creating a java class Sample.java
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
public class Sample
{
public static void main(String[] args) throws ClassNotFoundException
{
// load the sqlite-JDBC driver using the current class loader
Class.forName("org.sqlite.JDBC");
Connection connection = null;
try
{
// create a database connection
connection = DriverManager.getConnection("jdbc:sqlite:sample.db");
Statement statement = connection.createStatement();
statement.setQueryTimeout(30); // set timeout to 30 sec.
statement.executeUpdate("DROP TABLE IF EXISTS person");
statement.executeUpdate("CREATE TABLE person (id INTEGER, name STRING)");
int ids [] = {1,2,3,4,5};
String names [] = {"Peter","Pallar","William","Paul","James Bond"};
for(int i=0;i<ids.length;i++){
statement.executeUpdate("INSERT INTO person values(' "+ids[i]+"', '"+names[i]+"')");
}
//statement.executeUpdate("UPDATE person SET name='Peter' WHERE id='1'");
//statement.executeUpdate("DELETE FROM person WHERE id='1'");
ResultSet resultSet = statement.executeQuery("SELECT * from person");
while(resultSet.next())
{
// iterate & read the result set
System.out.println("name = " + resultSet.getString("name"));
System.out.println("id = " + resultSet.getInt("id"));
}
}
catch(SQLException e){ System.err.println(e.getMessage()); }
finally {
try {
if(connection != null)
connection.close();
}
catch(SQLException e) { // Use SQLException class instead.
System.err.println(e);
}
}
}
}
The code will create a database named sample.db, inserting data into, and then prints the rows.
I want to fetch parameter name and parameter type of given prepared statement. I am using MySQL Database. But when I run my program it is throwing an error:
Exception in thread "main" java.sql.SQLException: Parameter metadata not available for the given statement
at this line
String paramTypeName = paramMetaData.getParameterTypeName(param);
I don't know why this is happening. Please anybody help me if possible.
Here's my code:
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ParameterMetaData;
import java.sql.PreparedStatement;
import java.sql.Statement;
public class Main {
public static void main(String[] args) throws Exception {
Connection conn = getMySqlConnection();
Statement st = conn.createStatement();
String query = "select * from survey where id > ? and name = ?";
PreparedStatement pstmt = conn.prepareStatement(query);
ParameterMetaData paramMetaData = pstmt.getParameterMetaData();
if (paramMetaData == null) {
System.out.println("db vendor does NOT support ParameterMetaData");
} else {
System.out.println("db vendor supports ParameterMetaData");
// find out the number of dynamic parameters
int paramCount = paramMetaData.getParameterCount();
System.out.println("paramCount=" + paramCount);
System.out.println("-------------------");
for (int param = 1; param <= paramCount; param++) {
System.out.println("param number=" + param);
String paramTypeName = paramMetaData.getParameterTypeName(param);
System.out.println("param SQL type name=" + paramTypeName);
}
}
pstmt.close();
conn.close();
}
public static Connection getMySqlConnection() throws Exception {
String driver = "com.mysql.jdbc.Driver";
String url = "jdbc:mysql://localhost:3306/mydb";
String username = "root";
String password = "";
Class.forName(driver);
Connection conn = DriverManager.getConnection(url, username, password);
return conn;
}
}
According to this
Should the driver generate simplified parameter metadata for PreparedStatements when no
metadata is available either because the server couldn't support preparing the statement, or
server-side prepared statements are disabled?
You have to set generateSimpleParameterMetadata to true
use a connection string similar to this
jdbc:mysql://localhost:3306/mydb?generateSimpleParameterMetadata=true
MySQL JDBC driver currently does not support it. I am solving the similar issue and came up with the following workaround:
include H2 database in your project (it can also run in embedded mode or in-memory)
translate your MySQL create database script to H2 syntax (or write it in ANSI so it is compatible with both)
compile prepared statements on H2 database first and get metadata from them - H2 database supports this function and SQL query syntax is similar in most cases - then save the obtained meta information for later use
there might be differences in data types, etc, but in general this should give you about 80% match with MySQL without too much hassle
I know it has much caveats, but it might work in some use cases.
Also consider upgrading MySQL database to 5.7, there are some enhancements related to prepared statements which may help, but I am not very deeply knowledgable about those:
http://dev.mysql.com/doc/refman/5.7/en/prepared-statements-instances-table.html
http://dev.mysql.com/doc/refman/5.7/en/prepare.html
You have not set the parameter to the prepared statements, without which you cannot get parameter metadata. so first set the parameter
pstmt.setInt(val)
pstmt.setString(val)
After adding the parameters you can get the meta data about the parameter.
Hope this helps.
Working with database in java requires a set of lines of code to be written. If the database connection is established again-n-again the same set of lines need to be repeated again-n-again which creates an overhead to programmer.
Hence, I am making a utility class which works as a database agent. The method of this class will be responsible for all the database related stuff from establishing a connection to executing a query and returning the result.
My class goes like this -
package connect;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;
public class Connector
{
private ResultSet rs;
public String password;
public void connect(String dbUrl, String dbClass, String dbUserName, String dbPassword, String query)
{
try
{
Class.forName(this.dbClass).newInstance();
Connection conn = DriverManager.getConnection (dbUrl, dbUserName, dbPassword);
Statement stmt = conn.createStatement();
rs = stmt.executeQuery(query);
while(rs.next())
{
this.password = (String) rs.getObject(1);
}
conn.close();
} //end try
catch(Exception e)
{
e.printStackTrace();
}
}
}
When a programmer needs a query to be executed, below lines can be written for that purpose -
Connector con = new Connector();
con.connect("your database URL",
"your database driver",
"your database username",
"your database password",
"your query");
My question here is that right now I am retreiving the data from ResultSet in the connect method itself. The retreived data can vary from query-to-query hence I want a data structure in which I can store the data from rs in connect() method and return it.
It will look like -
<data structure> result = con.connect("your database URL",
"your database driver",
"your database username",
"your database password",
"your query");
Can someone please suggest me a data structure for this purpose?
Not sure why you're re-inventing this particular wheel, and it seems like if you're repeatedly connecting for every query you're basically writing yourself out of any performance, but why not just use RowSetDynaClass if you're not going to map to objects?
Just be aware that there are a ton of pre-existing solutions that have been tested and proven. And use connection pools; creating connections is expensive.
There is a lot of Open Source, implementation like the one you want to do above.
Spring JDBCTemplate for example.
If you can't use any libraries already available to solve your problem, you could use
Vector<Map<String, Object>>
Where String contains column name and Object is the value of the column. Each element in the Vector corresponds to a row of the ResultSet. This may not be the most efficient data structure but should get the job done.