I have the following table cl:
id - int(10) primary key
contact - int(10)
list - int(10)
With a unique index on contact and list. When I run concurrently the following query in batch by 100 records:
INSERT INTO cl(list, contact) VALUES (?, ?) ON DUPLICATE KEY UPDATE cl.id = cl.id
Under high pressure it fails in about 20% with the following error:
java.sql.SQLSyntaxErrorException: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'ON DUPLICATE KEY UPDATE cl.id = cl.id' at line 1
80% of the queries runs just fine. When I rerun failed queries with the same parameters, again 20% fail.
Why some of the queries fail and then produce no errors when executed for the second time?
Changing query to
INSERT IGNORE INTO cl(list, contact) VALUES (?, ?)
solved the issue. Though it is unclear why mysql was throwing java.sql.SQLSyntaxErrorException instead of something more unambiguous.
Related
I'm running a script to insert some data in a MySQL database, and it runs properly in the MySQL workbench. However, when I try to run it from Java via the JDBC, I get an error. The script is:
INSERT INTO `pa_record` (`username`, `pa_record_type`, `record_time`) VALUES (?, ?, CURRENT_TIMESTAMP);
SET #record_id := 1;
INSERT INTO `pa_crud` (`pa_record_id`, `table_name`) VALUES (#record_id, ?);
The error I get from the JDBC is
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 'SET #record_id := 1;
INSERT INTO pa_crud (pa_record_id, table_name) VALUES' at line 2
Any ideas?
Many (most?) database access libraries do not allow multiple statements in a single execute; those that do, usually need to have the feature activated with a setting change. It's likely not complaining about the SET, but that you had anything after the end of the first query at all.
When issuing a bulk insert statement, how can we ignore (supress) the exception thrown by DB and/or JDBC driver ?
Lets say I want to bulk insert some Users and I have an Id as a unique key
INSERT INTO users
(id,name,age,email,pass_code)
VALUES
(1,'Mark',18,'mail#mail.com',123),
(2,'Zak',18,'mail#mail.com',123),
(3,'Djigi',18,'mail#mail.com',123),
(1,'James Petkov',18,'mail#mail.com',123), --Duplicated by id ?
(4,'Kinkinikin',18,'mail#mail.com',123),
(5,'A bula bula ',18,'mail#mail.com',123),
(6,'Shakazulo',18,'mail#mail.com',123);
How to tell the engine MySQL/PostgreSQL to continue inserting the remaining records ?
Is this supported in SQL at all ?
In PostgreSQL, you can ignore the failing rows with
INSERT ... ON CONFLICT (id) DO NOTHING;
A more general solution is to run each INSERT separately and ignore errors.
How do I need to handle a unique_constraint on non-key attribute ? I am using Oracle database.
I have a set unique constraint on username field. (emp_id is primary key but I have to check on emp_username). When I intentionally insert a duplicate username, my program is stuck, instead of displaying any error in console while debugging.
String sql = "insert into employee(emp_username, emp_password) values (\'"+username+"\', \'"+password+"\')";
statement.executeUpdate(sql);
But on command line duplicate insertion shows an error:
ERROR at line 1:
ORA-00001: unique constraint (USMAN.UNIQUE_USERNAME) violated
it seems here that the problem is not in your code(Your code is fine), it's in the data that you are trying to insert, the username column is unique, so you can't insert value multiple times in that column .
I have a table named CUSTOMERS with the following columns :
CUSTOMER_ID (NUMBER), DAY(DATE), REGISTERED_TO(NUMBER)
There are more columns in the table but it is irrelevant to my question as only the above columns are defined together as the primary key
In our application we do a large amount of inserts into this table so we do not use MERGE but use the following statement :
INSERT INTO CUSTOMERS (CUSTOMER_ID , DAY, REGISTERED_TO)
SELECT ?, ?, ?
FROM DUAL WHERE NOT EXISTS
(SELECT NULL
FROM CUSTOMERS
WHERE CUSTOMER_ID = ?
AND DAY = ?
AND REGISTERED_TO = ?
)";
We use a PreparedStatement object using the batch feature to insert a large number of records collected through the flow of the application per customer.
Problem is that sometimes I get the following error :
ORA-00001: unique constraint (CUSTOMERS_PK)
violated
Strange thing is that when I do NOT use batch inserts and insert each record one by one (by simply executing pstmt.execute()) there are no errors.
Is it something wrong with the insert statement ? the jdbc driver ? Am I not using the batch mechanism correctly ?
Here is a semi-pseudo-code of my insertion loop :
pstmt = conn.prepareStatement(statement);
pstmt.setQueryTimeout(90);
for each customer :
- pstmt.setObject(1, customer id);
- pstmt.setObject(2, current day);
- pstmt.setObject(3, registered to);
- pstmt.addBatch();
end for
pstmt.executeBatch();
It is all enclosed in a try/catch/finally block making sure the statement and connection are closed at the end of this process.
I guess you are using several threads or processes in parallel, each doing inserts. In this case, Oracle's transaction isolation feature defeats your attempt to do the merge, because sometimes the following is bound to happen:
session A runs your statement, inserts a row (x,y,z)
session B runs the same statement, tries to insert row (x,y,z), gets a lock and waits
session A commits
session B receives the "unique constraint violated" error
That's because until session A commits, session B doesn't see the new row, so it tries to insert the same.
I have a Table [Name Table] and an associated table workSchedule. I'm using Hibernate 3.6.7.Final to generate my query. The result is:
update Personnel.dbo.[Name Table] set workSchedule=? where [Name IRC]=?
Which throws an Exception:
11-22#10:30:41 WARN [] JDBCExceptionReporter - SQL Error: 8624, SQLState: S0001
11-22#10:30:41 ERROR [] JDBCExceptionReporter - Internal Query Processor Error: The query processor could not produce a query plan. For more information, contact Customer Support Services.
[Name Table].workSchedule is a foreign key defined thus:
ALTER TABLE [Name Table] ADD workSchedule VARCHAR(34)
FOREIGN KEY REFERENCES workSchedule(id);
workSchedule.id is defined like this:
CREATE TABLE workSchedule
( /* format = letter-days-lunch EX: A-5-1 */
id AS CASE lunch
WHEN 1 THEN scheduleLetter+'-'+CONVERT(VARCHAR, scheduleDays)+'-'+'1'
ELSE scheduleLetter+'-'+CONVERT(VARCHAR, scheduleDays)+'-'+'5'
END PERSISTED NOT NULL,
/* rest of table follows */
);
If I copy paste the above update query into SSMS and plug values directly in for the ?s it works.
UPDATE:
I just tried changing out the PRIMARY KEY of the table WorkSchedule for an INT IDENTITY column. I left renamed id to shift and otherwise left it as column on the table. I also updated both POJO's and .hbm.xml files. The update query still fails, with the same exception.
I'm listing this as an answer because it's what I ended up doing to solve my problem.
I completely removed the calculated field on WorkSchedule.
I implemented the calcualations as a getter in the the POJO instead.
Re-tooled workschedule to use an IDENTITY for the PK
and re-linked [Name Table] to the new IDENTITY field instead. now it all works.