I have the following MySQL query which uses variables. The query is being used in an application which uses Hibernate. I have gotten around handling the assignments in hibernate by adding two backslashes as others have mentioned on stack.
However, when I try to run my application, I receive the following error:
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 'PREPARE stmt1 from #sql_max; EXECUTE stmt1' at line 1
My sql query in hibernate is as follows:
private static final String COUNT_INTERQUARTILE_SQL
= " SET #sql_max \\:=('SELECT ''Max'' AS quartile, max(visit.id) as id " +
" FROM carecube.visit order by visit.id ');" +
" PREPARE stmt1 from #sql_max;" +
" EXECUTE stmt1;";
I'm unsure where the error is, o.O, am I missing something obvious? cheers.
EDIT: The statement which invokes the SQL:
#Override
public List<InterQuartileRange> interQuartileRange() {
// TODO Auto-generated method stub
return this.template.execute(new HibernateCallback<List<InterQuartileRange>>() {
#SuppressWarnings("unchecked")
#Override
public List<InterQuartileRange> doInHibernate(Session session) throws HibernateException {
Query query = session.createSQLQuery(COUNT_INTERQUARTILE_SQL);
return (List<InterQuartileRange>)query.list();
}
});
}
Related
The database update method that I'm working on in my java program, doesn't update the database. Only if I run the read method inside the same class, it will show the updated version of the database but it doesn't actually update the database.
What I do is I run the unit_elimination(2) method inside my main class and then it doesn't update the database ( it should turn the status column of the row with ID=1 inside main_table to 2 but it stays the same in the database ) . Then I use the showname method to read the table and it shows the updated number but the database isn't actually getting updated.
package com.company;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.Statement;
import java.sql.PreparedStatement;
import java.sql.*;
public class Stdn implements AutoCloseable{
private Connection connection;
private PreparedStatement preparedStatement;
private ResultSet resultSet;
public Stdn() throws SQLException {
connection = DriverManager
.getConnection("jdbc:mysql://localhost:1522/juni_project" , "root", "password");
connection.setAutoCommit(false);
}
public void showName(String A , String B) throws SQLException{
preparedStatement = connection.prepareStatement("select "+ A + " from " + B + ";" );
resultSet = preparedStatement.executeQuery();
while (resultSet.next()){
System.out.println(resultSet.getString(1));
}
}
public void update(String A , String B , int C , int D) {
try{
PreparedStatement preparedStatement = connection.prepareStatement("UPDATE "+ A + " SET " + B + " =? WHERE ID = ? ;");
preparedStatement.setInt(1,C);
preparedStatement.setInt(2, D);
preparedStatement.executeUpdate();
}
catch (SQLException e){
System.out.println( " Could not update data to the database " + e.getMessage());
}}
public void unit_elimination(int X) throws SQLException {
update("main_table" ,"status", X , 1 );
}
#Override
public void close() throws Exception {
preparedStatement.close();
connection.close();
}}
Can you please help me find where the problem is I've been stuck on this for a few days and have little time to spare.
You disable auto-commit after creating the connection. This means you have to explicitly commit (using connection.commit()) before changes are visible to other transactions. And, IIRC, MySQL or MySQL Connector/J will rollback the transaction if it is still active when you close the connection.
In other words, your changes are 1) never visible to other transactions and 2) once you close the connections, your changes are gone.
TL;DR: Add a connection.commit() where your unit-of-work is complete and you want the changes to become permanent. Or consider if for your program using auto-commit is good enough, and remove the connection.setAutoCommit(false); from your code.
ConnectionClass:
Here I used stm.execute but I'm not getting an error. I also used executeUpdate but I'm also getting an error.
package com.company;
import java.sql.*;
class ConnectionClass {
private static Connection con = null;
private static Statement stm = null;
private static ConnectionClass connectionClass;
public void createConnection() {
try {
Class.forName("com.mysql.jdbc.Driver");
con = DriverManager.getConnection("jdbc:mysql://localhost:3306/mysql", "root", "root");
}
catch (Exception e) {
e.printStackTrace();
}
}
public void createTable() {
String Table_Name = "BOOK";
try {
stm = con.createStatement();
DatabaseMetaData dbm = con.getMetaData();
ResultSet rs = dbm.getTables(null, null, Table_Name, null);
if (rs.next()) {
System.out.println("Table" + Table_Name + "Already created");
} else {
String sql = "CREATE TABLE" + Table_Name + "(ID VARCHAR(200), title VARCHAR(200),author varchar(100),publisher varchar(100)";
stm.executeLargeUpdate(sql);
}
} catch (Exception ex) {
ex.printStackTrace();
}
}
public ConnectionClass() {
createConnection();
createTable();
}
}
MainClass:
Here I think the main class is working properly.
package com.company;
public class Main {
public static void main(String[] args) throws Exception {
ConnectionClass connectionClass = new ConnectionClass();
}
}
ERROR:
The method executeLargeUpdate was added in Java 8 / JDBC 4.2 and judging by the error it has not been implemented in the MySQL Connector/J version you are using.
The solution is simple: don't use any of the Large methods in the API, and instead use executeUpdate, or - better in the case of DML - execute. Alternatively, update to a newer version of MySQL Connector/J, as executeLargeUpdate is implemented in newer versions of MySQL Connector/J (eg 5.1.46, but at least 5.1.37 (the version that added support)).
You will also need to address the syntax error pointed out by Adil.
You have a syntax error in your query. You current SQL Query:
String sql = "CREATE TABLE" + Table_Name + "(ID VARCHAR(200), title VARCHAR(200),author varchar(100),publisher(100)";
Corrected SQL Query:
String sql = "CREATE TABLE" + Table_Name + "(ID VARCHAR(200), title VARCHAR(200),author varchar(100),publisher varchar(100)";
(You are asking mysql to create a column publisher, but where's the datatype? Simply specify the datatype and it will work.)
EDIT:
So, finally wrapping up this question, let's have a look at what Ora Docs have to say about this:
executeLargeUpdate:
default long executeLargeUpdate(String sql) throws SQLException
Executes the given SQL statement, which may be an INSERT, UPDATE, or DELETE statement or an SQL statement that returns nothing, such as an SQL DDL statement.
This method should be used when the returned row count may exceed Integer.MAX_VALUE - A constant holding the maximum value an int can have, 2^31-1.
Note:This method cannot be called on a PreparedStatement or CallableStatement.
The default implementation will throw UnsupportedOperationException. This method is introduced since JDK 1.8
Also note the above point as stated in the docs. The default implementation is to throw an UnsupportedOperationException. This means that different JDBC drivers can have different implementations of Statement class. They can either implement it or leave it unimplemented, and if you invoke the method in 2nd case, the method will throw an UnsupportedOperationException, as stated in the docs.
By checking the oracle docs for this method, you can get more information about it. So the possibility could be that the driver version you are using is not supporting this method, so please update tot eh latest version of this driver and try it out.
Below is my Java program. I am calling a PLSQL procedure to update the Employee name. I turned off the commit in the PLSQL code so that I can do the commit and rollback from Java code. But even after I turned off the auto commit and doing explicit rollback, still the details are updated in the table.
How? I have no idea, please help.
Here's my Java code. In PLSQL, it just read the value and does an update statement . No commits.
public class TestCommit {
public static void main(String[] args) throws SQLException, IOException {
CallableStatement callableStatement = null;
Connection conn = null;
try {
DriverManager.registerDriver(new oracle.jdbc.driver.OracleDriver());
conn = DriverManager
.getConnection("jdbc:oracle:thin:testuser/testpwd#//testdb:1521/testbx");
conn.setAutoCommit(false);
String sql = "{call testpkg.saveemployee(?,?)}";
callableStatement = conn.prepareCall(sql);
callableStatement.setString("name", "spider");
callableStatement.setString("id", "A101");
callableStatement.executeQuery();
conn.rollback();
} catch (Exception ex) {
ex.printStackTrace();
} finally {
// Close the statement
callableStatement.close();
// Close the connection
conn.close();
}
}
}
edit: PLSQL
CREATE OR REPLACE PROCEDURE saveemployee(
name IN employee.ename%TYPE,
id IN employee.eid%TYPE)
IS
BEGIN
UPDATE employee SET ename = name WHERE eid = id;
END;
My bad, I was calling a wrong procedure, there were two versions of the same procedure in two different packages,
one has the commit , the other one doesn't have the commit. I was calling the one that had the commit.
Now that the commit is removed from both procedures, my code seems to work now.
I am working on an application which performs communication with the Sqlite database. This is java application. Although I have here a little issue regarding db communication.
This is the SQL query in order to create a relation:
dao.createTable(connect, "CREATE TABLE IF NOT EXISTS volume.PERSON (PERSON_ID INTEGER PRIMARY KEY ASC NOT NULL, LAST_NAME TEXT, FIRST_NAME TEXT, STREET TEXT, CITY TEXT);");
#Override
public void createTable(Connection connect, String sql){
try {
Statement statement = connect.createStatement();
Boolean result = statement.execute(sql);
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
The following line (Boolean result = statement.execute(sql);) cause the NullPointerException:
Exception in thread "main" java.lang.NullPointerException
at org.sqlite.Stmt.execute(Stmt.java:113)
at database.ImplementationDAO.createTable(ImplementationDAO.java:25)
at main.TestPoint.main(TestPoint.java:32)
There is something wrong the SQL query, but I don't get what is the problem?
Any suggestions?
Best regards
Looks like your database connection is closed, try calling connect.isClosed() to verify.
I want to delete and insert triples from a sesame repository using SPARQL queries, and I want to execute both operations as a single transaction.
DELETE
INSERT
If an exception is thrown during the transaction, rollback is executed... but it seems not to work.
The problem is that, if an exception is thrown during the insert query, the rollback is executed, but the previously deleted triples are not recovered (Why?).
Here you have some code:
I have a class called OwlimConnector which wraps the repository connection and provides some methods to make SPARQL Queries.
In the constructor of this class, I set up the connection and I set the autocommit to false:
RemoteRepositoryManager repos_manager = RemoteRepositoryManager.getInstance(SERVER_URL, USER, PASSWORD);
repos_manager.initialize();
Repository ssr = repos_manager.getRepository(REPOSITORY);
rconn = ssr.getConnection();
rconn.setAutoCommit(false);
In OwlimConnector there is a method called executeUpdate:
public void executeUpdate(String queryString) throws RepositoryException, MalformedQueryException, UpdateExecutionException
{
Update up = rconn.prepareUpdate(QueryLanguage.SPARQL, queryPrefixString + queryString);
up.execute();
}
and these methods among others:
public void commit(){
rconn.commit();
}
public void rollback() {
rconn.rollback();
}
public void close(){
rconn.close();
}
On the other hand, I have a web service "updateUserGroup" wich uses the previous OwlimConnector and a data access object called UserGroupDAO:
#PUT
#Consumes(MediaType.APPLICATION_XML)
public Response updateUserGroup(UserGroup ug) {
try {
oc = new OwlimConnector();
} catch (OwlimInstantiationException e) {
return ResponseFactory.getError(e.getErrorMessage());
}
try {
UserGroupDAO ugdao = new UserGroupDAO(oc);
ugdao.delete(ug.getUri());
ugdao.add(ug);
oc.commit();
oc.close();
return ResponseFactory.getOK();
} catch (MandatoryFieldException e) {
oc.rollback();
oc.close();
return ResponseFactory.getError(e.getErrorMessage());
} catch (NotExistingResourceException e) {
oc.rollback();
oc.close();
return ResponseFactory.getError(e.getErrorMessage());
} catch (Exception e) {
oc.rollback();
oc.close();
return ResponseFactory.getError(new GenericException(e).getErrorMessage());
}
}
1 What ugdao.delete(ug.getUri()) does is to call the OwlimConnector method executeUpdate:
oc.executeUpdate("DELETE { " + usergroup + " ?p ?v . } WHERE { " + usergroup + " ?p ?v . }");
Here the triples are deleted even though there is no commit!
2 What ugdao.add(ug) does is:
To check that ug.getName() is not null or spaces, otherwise the MandatoryFieldException is thrown:
if (ug.getName() == null || ug.getName().equals("")){
throw new MandatoryFieldException("name");
}
Then, the data is inserted:
oc.executeUpdate("INSERT DATA { " + ug.getUri() + " a scmu:UserGroup ; scmu:hasName \"" + ug.getName() + "\" . }");
When ug.getName() is null or spaces the MandatoryFieldException exception is thrown and caught by updateUserGroup. Then the rollback is executed but the deleted triples are not recovered.
I donĀ“t know why this happens. Any Idea?
Thank you very much in advance
The solution is much easier than I thought. This is the answer I received from the Ontotext AD in the mailing list:
"you are using RemoteRepository so each update, is immediately sent to the remote repository at up.execute() and there it is autocommited immediately .
what you could do is instead of preparing and executing on each delete/add operation in your service to start collecting all individual updates (into a StringBuilder for instance) and on oc.commit() to prepare and execute the whole list of updates at once (and just clear the list on rollback, in case an exception is thrown)
Your update request can have multiple 'INSERT DATA' or 'DELETE DATA' updates ... "
And it works! Thank you.