Oracle Java Prepared Statement Insert if not exists - java

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) {
}
}
} }

Related

Why I keep getting the error : org.postgresql.util.PSQLException: ERROR: syntax error at or near "(" in my jdbc code?

I am trying to write a method in jdbc in order to update some columns in my database (postgresql)
Here is what I have written so far:`
public void showRoomBookings(int clientID) {
Scanner myObj = new Scanner(System.in);
Statement st;
try {
st = conn.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE,ResultSet.CONCUR_UPDATABLE);
ResultSet res = st.executeQuery("SELECT rb.\"hotelbookingID\",rb.\"roomID\",rb.\"bookedforpersonID\",rb.checkin,rb.checkout,rb.rate\r\n"
+ "FROM roombooking rb ,hotelbooking hb\r\n"
+ "where rb.\"bookedforpersonID\"=hb.\"bookedbyclientID\"\r\n"
+ "AND hb.\"bookedbyclientID\"="+clientID+"\r\n"
+ "order by rb.\"hotelbookingID\"");
int j=1;
while(res.next()) {
System.out.println(j+")roomID:"+res.getInt(2)
+" bookedforpersonID:"+res.getInt(3)+" checkin:"+res.getDate(4)+" checkout:"+res.getDate(5)
+" rate:"+res.getInt(6));
j++;
}
System.out.println("Enter the number of the room you want to update:");
int answer = myObj.nextInt();
ResultSet res1 = st.executeQuery("Select t2.\"hotelbookingID\",t2.\"roomID\",t2.\"bookedforpersonID\",t2.checkin,t2.checkout,t2.rate\r\n"
+ "From \r\n"
+ "(\r\n"
+ " Select \r\n"
+ " Row_Number() Over (Order By t1.\"hotelbookingID\") As RowNum\r\n"
+ " , *\r\n"
+ " From (\r\n"
+ "SELECT rb.\"hotelbookingID\",rb.\"roomID\",rb.\"bookedforpersonID\",rb.checkin,rb.checkout,rb.rate\r\n"
+ "FROM roombooking rb ,hotelbooking hb\r\n"
+ "where rb.\"bookedforpersonID\"=hb.\"bookedbyclientID\"\r\n"
+ "AND hb.\"bookedbyclientID\"=107\r\n"
+ "order by rb.\"hotelbookingID\"\r\n"
+ " )t1\r\n"
+ ") t2\r\n"
+ "Where RowNum = "+answer);
System.out.println("You chose room: ("+answer+")");
while(res1.next()) {
System.out.println(res1.getInt(1)+" roomID:"+res1.getInt(2)
+" bookedforpersonID:"+res1.getInt(3)+" checkin:"+res1.getDate(4)+" checkout:"+res1.getDate(5)
+" rate:"+res1.getInt(6));
res1.updateInt("rate", 40);
res1.updateRow();
}
res.close();
res1.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
In the first ResultSet res I just project the roombookings bases on the clientID and then with ResultSet res1 I choose one of them. My console looks like this:
The problem here is that when I try to update rate :
res1.updateInt("rate", 40);
res1.updateRow();
I get the following message:
org.postgresql.util.PSQLException: ERROR: syntax error at or near "("
Position: 8 at
postgresql#42.2.20.jre7/org.postgresql.core.v3.QueryExecutorImpl.receiveErrorResponse(QueryExecutorImpl.java:2553)
at
postgresql#42.2.20.jre7/org.postgresql.core.v3.QueryExecutorImpl.processResults(QueryExecutorImpl.java:2285)
at
postgresql#42.2.20.jre7/org.postgresql.core.v3.QueryExecutorImpl.execute(QueryExecutorImpl.java:323)
at
postgresql#42.2.20.jre7/org.postgresql.jdbc.PgStatement.executeInternal(PgStatement.java:481)
at
postgresql#42.2.20.jre7/org.postgresql.jdbc.PgStatement.execute(PgStatement.java:401)
at
postgresql#42.2.20.jre7/org.postgresql.jdbc.PgPreparedStatement.executeWithFlags(PgPreparedStatement.java:164)
at
postgresql#42.2.20.jre7/org.postgresql.jdbc.PgPreparedStatement.executeUpdate(PgPreparedStatement.java:130)
at
postgresql#42.2.20.jre7/org.postgresql.jdbc.PgResultSet.updateRow(PgResultSet.java:1445)
at lol.DbApp.showRoomBookingss(DbApp.java:246) at
lol.DbApp.main(DbApp.java:290)
Here is my postgresql final result(the same as the last line from the console above):
EDIT: SQL CODE:
Select
t2."hotelbookingID",
t2."roomID",
t2."bookedforpersonID",
t2.checkin,
t2.checkout,
t2.rate
From(
Select
Row_Number() Over (
Order By
t1."hotelbookingID"
) As RowNum,
*
From
(
SELECT
rb."hotelbookingID",
rb."roomID",
rb."bookedforpersonID",
rb.checkin,
rb.checkout,
rb.rate
FROM
roombooking rb,
hotelbooking hb
WHERE
rb."bookedforpersonID" = hb."bookedbyclientID"
AND hb."bookedbyclientID" = 107
order by
rb."hotelbookingID"
) t1
) t2
Where
RowNum = 3
group by
t2."hotelbookingID",
t2."roomID",
t2."bookedforpersonID",
t2.checkin,
t2.checkout,
t2.rate
Any help would be valuable.

I'm working on databases in my java class, and I need help figuring out how to update a specific value/column in the database

Here is my first class. This is where im building my table and plugging in some values. In the second class, I am only displaying firstName,lastName, and salary BUT I also need to display the salary once more, but this time adding an increase of 10%, or salary += salary*.1 to be clear
public class CreateEmployeeDB
{
public static void main(String[] args)
{
final String DB_URL = "jdbc:derby:EmployeeDB;create=true";
try
{
Connection conn =
DriverManager.getConnection(DB_URL);
dropTables(conn);
buildEmployees(conn);
conn.close();
}
catch (Exception ex)
{
System.out.println("ERROR: " + ex.getMessage());
}
}
public static void dropTables(Connection conn)
{
try
{
// Get a Statement object.
Statement stmt = conn.createStatement();
try
{
stmt.execute("DROP TABLE Employees");
}
catch(SQLException ex)
{
// No need to report an error.
// The table simply did not exist.
}
}
catch(SQLException ex)
{
System.out.println("ERROR: " + ex.getMessage());
ex.printStackTrace();
}
}
public static void buildEmployees(Connection conn)
{
try
{
Statement stmt = conn.createStatement();
stmt.execute("CREATE TABLE Employees (" +
"socialSecurityNumber VARCHAR(30) NOT NULL PRIMARY KEY, " +
"firstName VARCHAR(30), " +
"lastName VARCHAR(30), " +
"weeklySalary DOUBLE, " +
"birthday DATE, " +
"employeeType VARCHAR(30), " +
"departmentName VARCHAR(30) " +
")");
stmt.execute("INSERT INTO EMPLOYEES VALUES( " +
"'11-1111', " +
"'John', " +
"'Smith', " +
"1000.50, " +
"'1945-01-02', " +
"'salariedEmployee', " +
"'R&D')");
stmt.execute("INSERT INTO EMPLOYEES VALUES( " +
"'22-2222', " +
"'Sue', " +
"'Jones', " +
"865.00, " +
"'1961-02-03', " +
"'commissionEmployee', " +
"'SALES')");
stmt.execute("INSERT INTO EMPLOYEES VALUES( " +
"'33-3333', " +
"'Bob', " +
"'Lowis', " +
"950.25, " +
"'1958-10-05', " +
"'basePlusEmployee', " +
"'SALES')");
stmt.execute("INSERT INTO EMPLOYEES VALUES( " +
"'44-4444', " +
"'Karen', " +
"'Price', " +
"1100.15, " +
"'1972-05-25', " +
"'salariedEmployee', " +
"'HR')");
}
catch (SQLException ex)
{
System.out.println("ERROR: " + ex.getMessage());
}
}
}
here is my second class. How do I update the salary in here? I'm assuming I need to do something with SELECT? But I can't quite figure it out.
public class UpdateSalary
{
public static void main(String[] args)
{
final String DB_URL = "jdbc:derby:EmployeeDB";
try
{
Connection conn = DriverManager.getConnection(DB_URL);
showSalary(conn);
updateSalary(conn);
}
catch(Exception ex)
{
System.out.println("ERROR: " + ex.getMessage());
}
}
public static void showSalary(Connection conn)
{
final String DB_URL = "jdbc:derby:Personnel";
try
{
Statement stmt = conn.createStatement();
String sqlStatement = "SELECT * FROM Employees";
ResultSet result = stmt.executeQuery(sqlStatement);
System.out.println("\n\t\t\t\t Employees Report - Current Salary ");
System.out.println("-------------------------------");
System.out.println("\t\t\t First \t\t\tLast Salary");
while (result.next())
{
System.out.printf("%30s %30s $%5.2f\n",
result.getString("firstName"),
result.getString("lastName"),
result.getDouble("weeklySalary")
);
}
//conn.close();
}
catch(Exception ex)
{
System.out.println("ERROR: " + ex.getMessage());
}
}
public static void updateSalary(Connection conn)
{
final String DB_URL = "jdbc:derby:Personnel";
try
{
Statement stmt = conn.createStatement();
String sqlStatement = "SELECT weeklySalary FROM Employees ";
ResultSet result = stmt.executeQuery(sqlStatement);
System.out.println("\n\t\t\t\t Employees Report - Updated Salary ");
System.out.println("----------------------------------");
System.out.println("\t\t\t First \t\t\tLast Salary");
while (result.next())
{
System.out.printf("%30s %30s $%5.2f\n",
result.getString("firstName"),
result.getString("lastName"),
result.getDouble("weeklySalary")
);
}
conn.close();
}
catch(Exception ex)
{
System.out.println("ERROR: " + ex.getMessage());
}
}
}
i apologize for the messy code and weird formatting that you get in the output. If anyone has tips, I would appreciate it. Thank you for your time.
You can SELECT it by making the relevant changes and display the result directly. Although this does not affect the database's weeklySalary values.
SELECT firstName,lastName,weeklySalary*1.1 as weeklySalary FROM Employees
You can create a SQL statement using UPDATE with the updated salary value and then execute the SQL statement using executeUpdate(). This will update the Database's weeklySalary values. Then, simply display the result.
Under updateSalary(Connection conn) replace in accordance.
String updateSqlStatement = "UPDATE Employees SET weeklySalary = weeklySalary*1.1";
stmt.executeUpdate(updateSqlStatement);
String sqlStatement = "SELECT * FROM Employees";
ResultSet result = stmt.executeQuery(sqlStatement);

java sqlite - display select

These are my tables:
http://sqlfiddle.com/#!5/acdb1
I want to display in Java something like raport:
Connection c = null;
Statement stmt = null;
try {
Class.forName("org.sqlite.JDBC");
c = DriverManager.getConnection("jdbc:sqlite:project.db");
c.setAutoCommit(false);
System.out.println("Opened database successfully");
stmt = c.createStatement();
ResultSet rs = stmt.executeQuery( "SELECT stormtrooper.id, squad.id, platoon.id, company.id, battalion.id FROM stormtrooper\n" +
"INNER JOIN squad ON squad.id=stormtrooper.squad\n" +
"INNER JOIN platoon ON platoon.id=squad.platoon\n" +
"INNER JOIN company ON company.id=platoon.company\n" +
"INNER JOIN battalion ON battalion.id=company.battalion;" );
String log = "";
while ( rs.next() ) {
log+=rs.getInt("id") + " | ";
log+=rs.getInt("id") + " | ";
log+=rs.getInt("id") + " | ";
log+=rs.getInt("id") + " | ";
log+=rs.getInt("id") + "\n";
}
jTextArea1.setText(log);
rs.close();
stmt.close();
c.close();
} catch ( Exception e ) {
jTextArea1.setText( e.getClass().getName() + ": " + e.getMessage() );
}
SELECT statement is correct - I checked this. But when I try execute this in Java, I'm getting an error:
ambiguous column: 'id'
How should it looks like?
You have a lot of id columns in your SELECT statement
You have to change the columns names with some like this:
SELECT stormtrooper.id AS stormtrooper_id, squad.id AS squad_id, platoon.id AS platoon_id, company.id AS company_id, battalion.id AS battalion_id FROM ...

GAE query working for unit testing but not local testing

My unit testing working fine for this query, but when i run my app in local it doesn't find the column seller.
String statement = "SELECT * FROM " + TABLE_NAME + " "
+ "INNER JOIN " + DbSeller.TABLE_NAME + " seller ON video.seller = seller.id "
+ "WHERE video.name LIKE ?";
//create statement
PreparedStatement stmt = DataBase.getInstance().prepareStatement(statement);
//set data
stmt.setString(1, "%" + s + "%");
//send query
ResultSet rs = stmt.executeQuery();
//the result
while(rs.next()) {
Video v = new Video();
System.out.println("test === " + rs.getInt("seller.id")); // <---- EXCEPTION (Column not found!!!!)
set(rs, v);
listVideo.add(v);
}
stmt.close();
And if i do this instead, it is fine: (Just for the test i don't want ending up writing column by column which info i need)
String statement = "SELECT video.*, seller.id as seller_id FROM " + TABLE_NAME + " "
+ "INNER JOIN " + DbSeller.TABLE_NAME + " seller ON video.seller = seller.id "
+ "WHERE video.name LIKE ?";
//create statement
PreparedStatement stmt = DataBase.getInstance().prepareStatement(statement);
//set data
stmt.setString(1, "%" + s + "%");
//send query
ResultSet rs = stmt.executeQuery();
//the result
while(rs.next()) {
Video v = new Video();
System.out.println("test === " + rs.getInt("seller_id")); // <---- NO EXCEPTION
set(rs, v);
listVideo.add(v);
}
stmt.close();
Note: My app is running on the same offline database in MySQL, so the only difference is that i run this query through my app instead of the unit testing.
Column names seller_id (underscore) and seller.id (dot) look different to me

Spring JdbcTemplate Cannot Get Insert ID from MySQL

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()

Categories