I am trying to insert new entries into my database, but only the new entries. If a class with the crn that I am adding already exists in the database then I would like to skip it to not have duplicates.
Below is the code I have right now. I have tried a few different methods but I keep getting exception:
java.sql.SQLSyntaxErrorException: 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 'EXCEPT crn' at line 1
The database entry works fine without the "EXCEPT crn", but again it adds duplicates.
try {
String query = null;
try {
query = "INSERT INTO Classes (crn, subject, creditHours, title, capacity, instructor, schedule) "
+ "VALUES (?, ?, ?, ?, ?, ?, ?) EXCEPT crn";
} catch(Exception e) {
conn.close();
}
PreparedStatement preparedStmt = conn.prepareStatement(query);
preparedStmt.setInt(1, crn);
preparedStmt.setString(2, subject);
preparedStmt.setInt(3, creditHours);
preparedStmt.setString(4, title);
preparedStmt.setString(5, capacity);
preparedStmt.setString(6, instructor);
preparedStmt.setString(7, schedule);
preparedStmt.executeUpdate();
} catch (SQLException e) {
e.printStackTrace();
}
If a class with the crn that I am adding already exists in the database then I would like to skip it to not have duplicates.
In MySQL, I would recommend the insert ... on duplicate key syntax:
INSERT INTO Classes (crn, subject, creditHours, title, capacity, instructor, schedule)
VALUES (?, ?, ?, ?, ?, ?, ?)
ON DUPLICATE KEY UPDATE crn = VALUES(crn);
For this to work, you need a unique constraint (or the like) on column crn:
ALTER TABLE Classes ADD CONSTRAINT cs_classes_uniq_crn UNIQUE(crn);
Then, when an INSERT occurs that would generate a duplicate crn, the query goes to the UPDATE clause, that actually performs a no-op.
Can you alter the row or rows you want? You could just put a unique constraint on them so they can't accept columns that have the same value.
ALTER TABLE table_name
ADD UNIQUE (column_name);
If you need multiple columns you can add the constraint to the table like this:
ALTER TABLE table_name
ADD CONSTRAINT constraint_name UNIQUE (column1, column2, etc);
The SQL statement that you try to execute is invalid because MySql does not support EXCEPT.
Since you want to skip the insertion of rows that already exist you can use INSERT IGNORE:
query = "INSERT IGNORE INTO Classes (crn, subject, creditHours, title, capacity, instructor, schedule) "
+ "VALUES (?, ?, ?, ?, ?, ?, ?)";
but for this to work there should be a unique constraint for the column crn.It seems like it is the PRIMARY KEY of the table so it is already unique.
If there isn't a unique constraint for the column crn you can use NOT EXISTS like this:
query = "INSERT INTO Classes (crn, subject, creditHours, title, capacity, instructor, schedule) "
+ "SELECT ?, ?, ?, ?, ?, ?, ? "
+ "WHERE NOT EXISTS (SELECT 1 FROM Classes WHERE crn = ?)";
so you will have to pass as the 8th parameter of the Prepared Statement crn again:
preparedStmt.setInt(8, crn);
Related
I have java application that execute native query, I have tried to execute the query using entityManager.createNativeQuery, jdbcTemplate, and java.sql.PreparedStatement.executeUpdate, none succeeded. The query completed without error, but no data is inserted.
Here's my actual SQL:
WITH stmt AS (
INSERT INTO account_statements (
amount,
sum_amount,
available_balance,
previous_available_balance,
hold_amount,
previous_hold_amount,
type,
note,
partner_id,
incoming_transfer_id
)
(
SELECT
?,
?,
(available_balance + ?),
available_balance,
hold_amount,
hold_amount,
?,
?,
?::uuid,
?::uuid
FROM account_statements
WHERE partner_id = ?::uuid
ORDER BY created_at
DESC LIMIT 1
) RETURNING id, available_balance, hold_amount), debit AS (
INSERT INTO journals (
amount,
type,
account_name,
account_statement_id,
partner_id
) (
SELECT
?,
?,
?,
id,
?::uuid
FROM stmt
)
), credit AS (
INSERT INTO journals (
amount,
type,
account_name,
account_statement_id,
partner_id
) (
SELECT
?,
?,
?,
id,
?::uuid
FROM stmt
)
)
UPDATE partners
SET
available_balance = (select available_balance from stmt),
hold_amount = (select hold_amount from stmt)
WHERE id = ?::uuid;
Not sure what I did wrong, but when I tried the SQL above in pg console and replace all the placeholders, it worked. Does anyone have an idea why the SQL above is not working?
Sorry it's maybe an easy question but I can't find anything on Google. I'm parsing csvData with e.g. more than 100000 rows / objects. I want to check that ALL values for the attributes are valid before they get written into the database. Annotations like #Size or #Length do not help...
To give you an example:
Entity:
#Entity
#Data
public class Transaction {
#Size(max = 30)
private String timestamp;
}
The csv is parsed and the objects are written down in a List.
List<Transaction> transaction = new ArrayList<>();
// list will be filled
try {
databaseConnector.saveAllTransactions(transaction, transactionRepository);
} catch (ConstraintViolationException exc) {
System.out.println(exc.getMessage());
}
The error that appears after the 5th object.
Hibernate: insert into transaction (amount, customer_customer_id, discount, receipt_no, receipt_pos_no, timestamp, unit_price) values (?, ?, ?, ?, ?, ?, ?)
Hibernate: insert into transaction (amount, customer_customer_id, discount, receipt_no, receipt_pos_no, timestamp, unit_price) values (?, ?, ?, ?, ?, ?, ?)
Hibernate: insert into transaction (amount, customer_customer_id, discount, receipt_no, receipt_pos_no, timestamp, unit_price) values (?, ?, ?, ?, ?, ?, ?)
Hibernate: insert into transaction (amount, customer_customer_id, discount, receipt_no, receipt_pos_no, timestamp, unit_price) values (?, ?, ?, ?, ?, ?, ?)
Hibernate: insert into transaction (amount, customer_customer_id, discount, receipt_no, receipt_pos_no, timestamp, unit_price) values (?, ?, ?, ?, ?, ?, ?)
Validation failed for classes [com.stuff.project.entity.Transaction] during persist time for groups [javax.validation.groups.Default, ]
List of constraint violations:[
ConstraintViolationImpl{interpolatedMessage='muss zwischen 0 und 30 liegen', propertyPath=timestamp, rootBeanClass=class com.stuff.project.entity.Transaction, messageTemplate='{javax.validation.constraints.Size.message}'}
]
Only that you know how the method looks like.
public boolean saveAllTransactions(List<Transaction> transactions, TransactionRepository transactionRepository) {
transactionRepository.saveAll(transactions);
return true;
}
The only thing I could imagine is to go through the whole list of objects and check for each object the attributes for it's length like:
transactions.forEach(e -> e.getTimestamp().length != 30); ....
That does not seem to be very performance friendly...
First of all: performance shouldn't be your primary concern. You have a list with N entries, and when you want to check the string length for each of the N entries, hey: you have to iterate the N entries, and look at each one. Of course, you could theoretically do that in parallel, which, given "enough" data to work with, makes things quicker, at the cost of more CPU power being used.
The real problem: you start to implement "extra validation", instead of relying on your annotations. In other words: you are working "around" your framework. That is rarely a good idea.
Assuming we are talking generic Java (bean) annotations, the canonical answer would be to do two things:
to create a class that represents a list of your Transaction objects
to provide a custom validator that works on that list (and that knows to iterate all entries, and check that string length)
I know there are many questions regarding this issue but I still haven't found a solution for my problem.
I build a PreparedStatement in and pass variables but the error (Unknown column 'checkedAt' in 'field list') is persistent.
My code:
PreparedStatement stmt = conn.prepareStatement(
"IF NOT EXISTS (SELECT * FROM `suites` WHERE name = ?)
THEN INSERT INTO `suites` (`name`, `description`, `metaData`, `active`, `checkedAt`, `createdAt`) VALUES (?, ?, ?, ?, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP);
ELSE UPDATE `suites` SET `name` = ?, `description` = ?, `metaData` = ?, `active`= ?, `checkedAt` = CURRENT_TIMESTAMP WHERE `name`= ?; END IF;");
stmt.setString(1, suite.get("SuiteName"));
...
stmt.setInt(9, 1);
stmt.setString(10, suite.get("SuiteName"));
stmt.execute();
The column checkedAt is available in the database and filled. The issue appears only in the UPDATE part (ELSE clause) of the statement.
Does anyone can provide me a solution?
Thank you!
I am not sure if it is possible, but I want to create an insert query for a prepared-statement where the insert query consist of a join between two tables.
E.g. (perhaps a stupid example)
String sql = "INSERT INTO TABLE_A A (" +
"GenderId, Name, Surname, Age) VALUES (B.GenderId, ?, ?, ?) " +
"LEFT JOIN TABLE_B B ON A.GenderId = B.GenderId " +
"WHERE B.Gender = 'Male'";
PreparedStatement statement = conn.prepareStatement(sql);
statement.setString(1, "Bill");
statement.setString(2, "Gates");
statement.setInt(3, 50);
If I understand what you are trying to achieve you can use a SELECT statement to generate the values you want to insert.
INSERT INTO TABLE_A (GenderId, Name, Surname, Age)
SELECT b.GenderId, ?, ?, ? FROM TABLE_B B
WHERE b.Gender = 'Male'
There's some basic reading on the subject here
Hello friends i am running code given below which contains the setLogTimeEntery function and when this function is executed i am getting
"Error : java.sql.SQLException: ORA-00917: missing comma"
error and my database is oracle plese any one tell me wht is the problem.
public int setLogTimeEntery(Connection con, LogTimeBean ltb) {
int ans = 0;
try{
psmt=con.prepareStatement("Insert into TR_LogTime values((Select count(*) from Tr_LogTime) + 1 ,(select sysdate from dual) , Prj_Id=?,Area_Id=?,Actvity_Id=?,ID_No=?,Work_Date=(select to_date(?,'dd/mm/yyyy')from dual) ,Work_Hours=?,Division=?,Description=?,Remarks=?,Work_Week=?)");
psmt.clearParameters();
psmt.setString(1,ltb.getLt_Prj_Id());
psmt.setInt(2,ltb.getLt_Area_Id());
psmt.setInt(3,ltb.getLt_Actvity_Id());
psmt.setInt(4, ltb.getLt_ID_No());
psmt.setString(5, ltb.getLt_Work_Date());
psmt.setFloat(6,ltb.getLt_Work_Hours());
psmt.setInt(7,ltb.getLt_Division());
psmt.setString(8, ltb.getLt_Description());
psmt.setString(9, ltb.getLt_Remarks());
psmt.setInt(10, ltb.getLt_Work_Week());
ans=psmt.executeUpdate();
psmt.close();
}catch(Exception e){
System.err.println("Error : "+e);
}
return ans;
}
I don't think your Oracle SQL statement (as defined in the prepared statement) is valid. When using the insert into [table] values(...) syntax, you don't use column=value expressions.
If you're specifying all of the column values in the correct order, then use this:
psmt=con.prepareStatement("Insert into TR_LogTime values((Select count(*) from Tr_LogTime) + 1 ,(select sysdate from dual), ?, ?, ?, ?,(select to_date(?,'dd/mm/yyyy')from dual) ,?,?,?,?,?)");
Otherwise, if you're only specifying a subset of the columns, use the syntax of
insert into TR_LogTime (col1, col2, col3, ...) values (?, ?, ?, ...)
(I didn't specify the exact column names in your example since I don't know all of them)
More on this syntax.
try this:
Insert into TR_LogTime (XXX, YYY, Prj_Id, Area_id, Activity_Id, ID_No, Work_Date, Work_Hours, Division, Description, Remarks, Work_Week) values (
(Select count(*) from Tr_LogTime) + 1 , (select sysdate from dual) , ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
You'll need to replace XXX and YYY with the appropriate column names