I am trying to insert a row into a MySQL table and get it's insert ID. I am aware of the MySQL last_insert_id() function, I just cannot seem to get it to work. Currently, I am trying to use a function annotated as a transaction and I am only getting 0 returned. I am using Spring 3.1.
#Transactional (propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
private long insertTransactionRecord
(
int custID,
int porID,
String date,
short crvID
) {
m_template.update ("INSERT INTO " +
" transaction " +
"( " +
" por_id, " +
" cust_id, " +
" trans_date, " +
" crv_id " +
") " +
"VALUES " +
"( " +
" ?, " +
" ?, " +
" ?, " +
" ? " +
")",
new Object[] {
porID,
custID,
date,
crvID
});
return m_template.queryForLong ("SELECT " +
" last_insert_id() " +
"FROM " +
" transaction " +
"LIMIT 1");
}
Use Spring's built-in support for this rather than doing it yourself.
SqlUpdate insert = new SqlUpdate(ds, "INSERT INTO company (name) VALUES (?)");
insert.declareParameter(new SqlParameter(Types.VARCHAR));
insert.setReturnGeneratedKeys(true);
// assuming auto-generated col is named 'id'
insert.setGeneratedKeysColumnNames(new String[] {"id"});
insert.compile();
....
GeneratedKeyHolder keyHolder = new GeneratedKeyHolder();
insert.update(new Object[]{"test"}, keyHolder);
System.out.println(keyHolder.getKey().longValue());
taken from here http://www.codefutures.com/spring-dao/
public int createCompany(Company company) throws SQLException {
jdbcTemplate.update(
"INSERT INTO company (name) VALUES (?)",
company.getName()
);
return jdbcTemplate.queryForInt( "select last_insert_id()" );
}
if you noticed there's no FROM there
The documentation reveals that the syntax for getting the last insert ID is:
SELECT LAST_INSERT_ID()
Related
I have a hibernate native sql query joining three tables, and I'm trying to retrive 3 columns from the result
public void doTestQuery() {
try (Session session = HibernateUtilities.getSessionFactory().openSession()) {
transaction = session.beginTransaction();
String sql = "SELECT\r\n"
+ " users.username, \r\n"
+ " user_roles.role_name, \r\n"
+ " address.address\r\n"
+ "FROM\r\n"
+ " address\r\n"
+ " INNER JOIN\r\n"
+ " users\r\n"
+ " ON \r\n"
+ " address.iduser = users.iduser\r\n"
+ " INNER JOIN\r\n"
+ " user_roles\r\n"
+ " ON \r\n"
+ " users.iduser = user_roles.iduser";
NativeQuery query = session.createNativeQuery(sql);
List<Object[]> results = query.list();
for (Object[] arr : results) {
System.out.println(arr[0].toString() +" "+ arr[1].toString() +" "+ arr[2].toString());
}
transaction.commit();
}
If I replace the System.out.println with this code below, it gives me an error. Is there a way to cast objects from this kind of hibernate queries?
Users user = (Users) arr[0];
UserRoles userRole = (UserRoles) arr[1];
Address _address = (Address) arr[2];
System.out.println(user.getUsername() + userRole.getRolename() + _address.getAddress());
Hibernate requires special aliases to be able to fetch the data from a result set. For this purpose, Hibernate supports a special template in native SQL.
String sql = "SELECT "
+ " {u.*},"
+ " {r.*},"
+ " {a.*} "
+ "FROM "
+ " address a "
+ " INNER JOIN "
+ " users u "
+ " ON a.iduser = u.iduser "
+ " INNER JOIN "
+ " user_roles r "
+ " ON u.iduser = r.iduser";
NativeQuery query = session.createNativeQuery(sql);
query.addEntity("u", Users.class);
query.addEntity("r", UserRoles.class);
query.addEntity("a", Address.class);
I am try to find the costumer with the highest bill using this sql that I wrote , but apparently I run into this error :
Every derived table must have its own alias
This is what I wrote:
public static void findCustomerWithHighestBill(Connection c) throws SQLException {
String query = "SELECT CustomerID, CustomerName, CITY, sum(sum_all) As 'data'\r\n"
+ "FROM (SELECT *, sum(Price) As 'sum_all'\r\n"
+ " FROM (SELECT *, Customer.NAME AS \"CustomerName\"\r\n"
+ " FROM Transactions\r\n"
+ " INNER JOIN Product ON Product.ID = Transactions.ProductID\r\n"
+ " INNER JOIN Customer ON Customer.ID = Transactions.CustomerID)\r\n"
+ " GROUP BY CustomerID, ProductID\r\n"
+ " ) \r\n"
+ "GROUP BY CustomerID\r\n"
+ "ORDER BY data DESC";
Statement statement = c.createStatement();
ResultSet set = statement.executeQuery(query);
set.next();
System.out.println("CustomerID: " + set.getInt("CustomerID") +
", Name: " + set.getString("CustomerName") + ", City: " +
set.getString("CITY") + ", Bill: " + set.getFloat("data"));
}
Can please somoane help me zith this ?
Coming back ,
It seems that indeed ad most of you says in the comments I should identify my tables first but, apparently I also have miss to avoid the duplicate ID column.
Here goes my new query:
String query = "SELECT CID, CustomerName, City, sum(sum_all) As data" +
" FROM (SELECT *, sum(PPROD) As sum_all" +
" FROM (SELECT Product.ID as PID,Customer.ID as CID,Product.Price as PPROD,City, Customer.NAME AS CustomerName" +
" FROM Transactions" +
" INNER JOIN Product ON Product.ID = Transactions.ProductID" +
" INNER JOIN Customer ON Customer.ID = Transactions.CustomerID) As t2" +
" GROUP BY CID, PID" +
" ) As t1" +
" GROUP BY CID" +
" ORDER BY data DESC;";
I created a sql query to delete a row given the rowid. When I run the query there are no errors, however, the row doesn't get deleted.
String query = "DELETE FROM " + TABLE_NAME + " WHERE " + " rowid " + " = " + id;
db.execSQL(query);
Try this:
String query = "DELETE FROM " + TABLE_NAME + " WHERE rowid " + " = '" + id + "'";
db.execSQL(query);
But I personally prefer this way:
if (db.delete(TABLE_NAME, rowid+ " = ?", new String[]{id}) != 0) {
Log.i("row", "Has been deleted");
} else{
Log.i("row", "Has not been deleted");
}
SOLUTION: I used the vacuum function to regenerate the proper rowId. I was previously deleting rows where that rowId didn't exist.
i have a problem with Java PreparedStatement and Oracle.
In short I want to create a Batch Insert using Java in my Oracle DB. I try to do it with this code:
PreparedStatement preparedStmt = connection.prepareStatement(
"INSERT INTO EFM_BAS_DATA_CLEAN_NUM (date_measured, time_measured, value_reported, data_point_id) " +
" VALUES(?,?,?,?)");
PreparedStatement preparedStmt = connection.prepareStatement(query);
for (EfmBasDataCleanNum measure : measuresToInsert) {
preparedStmt.setString(1, new java.sql.Date(measure.getDateMeasured().getTime()));
preparedStmt.setString(2, measure.getTimeMeasured());
preparedStmt.setDouble(3, measure.getValueReported());
preparedStmt.setInt(4, measure.getDataPointId());
preparedStmt.addBatch();
}
try {
preparedStmt.executeBatch();
}catch (SQLException e){ ...
However when some record already exist in the table, I've this error:
ORA-00001: unique constraint (AFM.UNIQUE_EFM_CLEAN_NUM) violated
cause I've a constraint on this fields.
So, looking on line, I've find many solution.
I tried with this query:
String query = "INSERT INTO EFM_BAS_DATA_CLEAN_NUM (date_measured, time_measured, value_reported, data_point_id) "+
" SELECT TO_DATE(?,'DD/MM/YYYY HH24:MI:SS'),TO_DATE(?,'DD/MM/YYYY HH24:MI:SS'),?,? FROM DUAL "+
" MINUS "+
" SELECT date_measured, time_measured, value_reported, data_point_id FROM efm_bas_data_clean_num";
or with:
String query = " INSERT INTO EFM_BAS_DATA_CLEAN_NUM ( date_measured, time_measured, value_reported, data_point_id ) "
+" SELECT TO_DATE(?, 'DD/MM/YYYY HH24:MI:SS'), TO_DATE(?, 'DD/MM/YYYY HH24:MI:SS'),?,? FROM DUAL "
+" WHERE not exists("
+" SELECT * FROM EFM_BAS_DATA_CLEAN_NUM "
+" WHERE DATE_MEASURED=TO_DATE(?, 'DD/MM/YYYY HH24:MI:SS') "
+" AND TIME_MEASURED=TO_DATE(?, 'DD/MM/YYYY HH24:MI:SS') "
+" AND VALUE_REPORTED=? "
+" AND DATA_POINT_ID=? )";
and finally with:
String query = "MERGE INTO EFM_BAS_DATA_CLEAN_NUM bd1 USING ("
+" SELECT TO_DATE(?, 'DD/MM/YYYY HH24:MI:SS') as DATE_MEASURED, "
+" TO_DATE(?, 'DD/MM/YYYY HH24:MI:SS') as TIME_MEASURED,"
+" ? as VALUE_REPORTED,"
+" ? as DATA_POINT_ID FROM DUAL "
+" ) bd2 on (bd1.DATE_MEASURED=bd2.DATE_MEASURED AND"
+" bd1.TIME_MEASURED=bd2.TIME_MEASURED AND"
+" bd1.VALUE_REPORTED=bd2.VALUE_REPORTED AND"
+" bd1.DATA_POINT_ID=bd2.DATA_POINT_ID)"
+" WHEN NOT MATCHED THEN "
+" INSERT (date_measured, time_measured, value_reported, data_point_id) "
+" VALUES(bd2.DATE_MEASURED,bd2.TIME_MEASURED,bd2.VALUE_REPORTED,bd2.DATA_POINT_ID)";
But while the execution of query in AquaData Studio ever work (or rather when is a new record, it is inserted and when record already exists, it sn't inserted, without errors), on app running, I still have the same error:
ORA-00001: unique constraint (AFM.UNIQUE_EFM_CLEAN_NUM) violated
maybe I'm wrong?
Thanks!
The 'where not exists' version of your code should have worked.
I would double check that you are setting the ? values in your java code correctly, so that your insert values are the same as your 'where not exists' values.
I tried your code with my own tables and it worked. I used select 'X' instead of *, but that shouldn't matter. My sorydct_cert_key is a unique key.
private void testInsert() throws SQLException {
String first = "8ADA";
Integer second = 8;
String third = "ADA Failed";
String fourth = "EXC";
String sql = "INSERT INTO SORYDCT(SORYDCT_CERT_KEY," +
" SORYDCT_CERT_CODE," +
" SORYDCT_CERT_DESC," +
" SORYDCT_PROGRAM," +
" SORYDCT_COUNT_CODE)" +
" SELECT ?,?,?,?, NULL" +
" FROM DUAL" +
" WHERE NOT EXISTS ( SELECT 'X'" +
" FROM SORYDCT" +
" WHERE SORYDCT_CERT_KEY = ?)";
PreparedStatement insertStatement = null;
try {
insertStatement = conn.prepareStatement(sql);
insertStatement.setNString(1, first);
insertStatement.setInt(2, second);
insertStatement.setString(3, third);
insertStatement.setString(4, fourth);
insertStatement.setString(5, first);
insertStatement.executeUpdate();
conn.commit();
} catch (SQLException e) {
System.out.println(ERROR_STRING);
System.out.println("Failure while inserting records - 1");
onException(e);
} finally {
try {
insertStatement.close();
} catch (SQLException e) {
}
}
first = "TEST";
second = 0;
third = "Test";
fourth = "EXC";
System.out.println(sql);
insertStatement = null;
try {
insertStatement = conn.prepareStatement(sql);
insertStatement.setNString(1, first);
insertStatement.setInt(2, second);
insertStatement.setString(3, third);
insertStatement.setString(4, fourth);
insertStatement.setString(5, first);
insertStatement.executeUpdate();
conn.commit();
} catch (SQLException e) {
System.out.println(ERROR_STRING);
System.out.println("Failure while inserting records - 2 ");
onException(e);
} finally {
try {
insertStatement.close();
} catch (SQLException e) {
}
}
} }
I've been getting this ArrayStoreException in my code for loading records from one mysql table to another. I tried truncating the destination table and running my code again and it seems that it encounters the said exception randomly.
I was going to implement a (Spring) JdbcTemplate based DAO when i've encountered an ArrayStoreException during unit testing. I tried to recreate it with ordinary JDBC code and still encounter the error.
For my DDL:
All the columns are of type varchar, except for brthdate and birthdate which are of type Date. DEFAULT CHARSET=utf8
My code snippet:
employeesSql = "select id_no, " +
"lastname, " +
"frstname, " +
"mdlename, " +
"brthdate,sex, " +
"sss_no, " +
"tin_no " +
"from lms.pms_empf " +
"where length(trim(id_no)) > 0 " +
"and id_no <> '000000' " +
" ORDER BY id_no";
employeeSql = "select count(*) "
+ "from dim_employees "
+ "where id_no=?";
updateSql = "update dim_employees " +
"set last_name = ?, " +
"first_name = ?, " +
"middle_name = ?, " +
"birthdate = ?, " +
"sex = ?, " +
"sss_no = ?, " +
"tin_no = ? " +
"where id_no = ?";
insertSql = "insert into dim_employees " +
"(id_no, last_name, first_name, " +
"middle_name,birthdate, sex, sss_no, tin_no) " +
"values (?,?,?,?,?,?,?,?)";
employeesStmt = con.createStatement();
employeeStmt = con.prepareStatement(employeeSql);
updateStmt = con.prepareStatement(updateSql);
insertStmt = con.prepareStatement(insertSql);
employeesCursor = employeesStmt.executeQuery(employeesSql);
while (employeesCursor.next()) {
idNo = new String(employeesCursor.getBytes(1), "UTF-8");
lastName = new String(employeesCursor.getBytes(2), "UTF-8");
firstName = new String(employeesCursor.getBytes(3), "UTF-8");
middleName = new String(employeesCursor.getBytes(4), "UTF-8");
birthDate = employeesCursor.getDate(5);
sex = new String(employeesCursor.getBytes(6), "UTF-8");
sssNo = new String(employeesCursor.getBytes(7), "UTF-8");
tinNo = new String(employeesCursor.getBytes(8), "UTF-8");
employeeStmt.setString(1, idNo);
employeeCursor = employeeStmt.executeQuery();
while (employeeCursor.next()) {
if (employeeCursor.getInt(1) > 0) {
//update
updateStmt.setString(1, lastName);
updateStmt.setString(2, firstName);
updateStmt.setString(3, middleName);
updateStmt.setDate(4, birthDate);
updateStmt.setString(5, sex);
updateStmt.setString(6, sssNo);
updateStmt.setString(7, tinNo);
updateStmt.setString(8, idNo);
updateStmt.executeUpdate();
updateStmt.executeUpdate();
}
else {
//insert
insertStmt.setString(1, idNo);
insertStmt.setString(2,lastName);
insertStmt.setString(3, firstName);
insertStmt.setString(4, middleName);
insertStmt.setDate(5, birthDate);
insertStmt.setString(6, sex);
insertStmt.setString(7, sssNo);
***//exception points here** insertStmt.setString(8, tinNo);
insertStmt.executeUpdate();
insertStmt.clearParameters();
}
}
employeeStmt.clearParameters();
Stack trace:
......
Caused by: java.lang.ArrayStoreException
at java.lang.String.getChars(String.java:854)
at com.mysql.jdbc.PreparedStatement.setString(PreparedStatement.java:4520)
......
at com.vdc.lmsprocs.EmployeeProc.setEmployees(EmployeeProc.java:135)
......
I'm sorry for the long post. I clearly could not explain well enough what happened here. It's the first time i've encountered such a flaw.
Thanks in advance.