I am using a single Spring JDBC update to make an update to two tables in my Postgres database. My SQL query is as follows:
UPDATE accounts SET last_transaction_amount = :transaction_amount WHERE acct_num = :acct_num; INSERT INTO transactions (transaction_amout) VALUES (:transaction_amount);
Using NamedParameterJdbcTemplate#update, I have no issue executing this query and achieving the expected results.
The transactions table generates a sequential transaction identifier, and I want to return this to my application.
I've tried passing a GeneratedKeyHolder in the update call. This is returning the error "A result was returned when none was expected". Docs link.
I've tried passing a GeneratedKeyHolder and array of column names (new String[] {"transaction_id"}). This is returning the error that the column doesn't exist. Note this method call does work to return the transaction id when I only pass the INSERT query without the preceding UPDATE query. Docs link.
How can I retrieve the generated key? Thank you!
You seem to be looking for the RETURNING clause. Assuming that the serial number is called transaction_id:
INSERT INTO transactions (transaction_amout)
VALUES (:transaction_amount)
RETURNING transaction_id;
I have a table where it has columns as
Task_Track
TaskID Number (PK AutoGeneratedSequence)
TaskCd Varchar2
RefCd Varchar2
RefID varchar2
Params varchar2
...etc
I am working on a scenario where I run a select query on this table get the result set.
Select * from Task_Track where RefCd = ? and RefID = ? and TaskCd = ?;
If i don't have any results I will insert a new task with RefCd RefID TaskCd Params values. Params is ususaly a person_id related to the task.
If i get the resultset I will append the new param and update the resultset.
if(resultset!=null and resultSet.length()>0)
update params logic
else
insert new task logic.
This is working as expected in a sequential run.
But when I have 2 parallel queues running and get the same RefCd RefID TaskCd values at the same time.
My first bucket is finding the resultset and is going to perform the update logic as expected but the second queue is not able to find the result and is going into insert logic.
From what I understand even if the first queue has locked the row for the update, the second queue should not have any problems with the read and should fail while updating because of the lock if the first queue hasn't released the lock. But my read itself is failing where it is not throwing any exception but returning an empty resultset(length=0). Because of which it is moving into insert logic.
Is it possible that the read is affected by the update happening in parallel? If so how should I resolve it?
Note: I am using Oracle 11G and Java8 with Websphere 9
Thank you
You need to cache the resultSet before make another request. Try this:
CachedRowSet crs = RowSetProvider.newFactory().createCachedRowSet();
crs.populate(myResultSet);
In MySQL, if you specify ON DUPLICATE KEY UPDATE and a row is inserted that would cause a duplicate value in a UNIQUE index or PRIMARY KEY, an UPDATE of the old row is performed. For example, if column a is declared as UNIQUE and contains the value 1, the following two statements have identical effect:
INSERT INTO table (a,b,c) VALUES (1,2,3)
ON DUPLICATE KEY UPDATE c=c+1;
UPDATE table SET c=c+1 WHERE a=1;
I don't believe I've come across anything of the like in T-SQL. Does SQL Server offer anything comparable to MySQL's ON DUPLICATE KEY UPDATE?
I was surprised that none of the answers on this page contained an example of an actual query, so here you go:
A more complex example of inserting data and then handling duplicate
MERGE
INTO MyBigDB.dbo.METER_DATA WITH (HOLDLOCK) AS target
USING (SELECT
77748 AS rtu_id
,'12B096876' AS meter_id
,56112 AS meter_reading
,'20150602 00:20:11' AS time_local) AS source
(rtu_id, meter_id, meter_reading, time_local)
ON (target.rtu_id = source.rtu_id
AND target.time_local = source.time_local)
WHEN MATCHED
THEN UPDATE
SET meter_id = '12B096876'
,meter_reading = 56112
WHEN NOT MATCHED
THEN INSERT (rtu_id, meter_id, meter_reading, time_local)
VALUES (77748, '12B096876', 56112, '20150602 00:20:11');
There's no DUPLICATE KEY UPDATE equivalent, but MERGE and WHEN MATCHED might work for you
Inserting, Updating, and Deleting Data by Using MERGE
You can try the other way around. It does the same thing more or less.
UPDATE tablename
SET field1 = 'Test1',
field2 = 'Test2'
WHERE id = 1
IF ##ROWCOUNT = 0
INSERT INTO tablename
(id,
field1,
field2)
VALUES (1,
'Test1',
'Test2')
SQL Server 2008 has this feature, as part of TSQL.
See documentation on MERGE statement here - http://msdn.microsoft.com/en-us/library/bb510625.aspx
SQL server 2000 onwards has a concept of instead of triggers, which can accomplish the wanted functionality - although there will be a nasty trigger hiding behind the scenes.
Check the section "Insert or update?"
http://msdn.microsoft.com/en-us/library/aa224818(SQL.80).aspx
I see there are two ways to create update query in Hibernate. First you can go with the standard approach where we have hql like:
Query q = session.createQuery("update" + LogsBean.class.getName() + " LogsBean " + "set LogsBean.jobId= :jobId where LogsBean.jobId= :oldValue ");
q.setLong("jobId", jobId);
q.setLong("oldValue", 0);
return q.executeUpdate();
or we can go and run
getHibernateTemplate.saveorupdate(jobId);
Now am getting java.lang.IllegalArgumentException: node to traverse cannot be null! on running first query and am not sure hwo to provide condition in getHibernateTemplate example, i want to update jobIds in log table whose value matches 0 and so i want to run something like
Update logs set jobId = 23 where jobId = 0
Above is the simple sql query that I am trying to run but I want to run this via hibernate, tried couple ways but it is not working, any suggestions?
Update:
As noted by Jeff, issue was not having space after update and so that issue got resolved but still values are not updated, i have updated show_sql true for hibernate and checking what could be the cause of the issue, will be running query generated by hibernate to run again db and see if records are updated.
Just a few things that might help you to resolve this:
What does .executeUpdate() return, 0 (as it did not update any
rows)?
Does it throw a HibernateException that you are
silently catching or rethrowing?
Which FlushMode do you have configured?
Does the update get to the DB? You could switch on the query log for your DB server.
INSERT INTO [UPLOAD_FILE_RECORD_FIELDS_DATA]([RECORD_ID], [FIELD_ORDER], [FIELD_VALUE], [ERROR_CODE])
select ?,?,?,?
union all
select ?,?,?,?
union all
select ?,?,?,?
I have to insert multiple records into one table.So i am using query as below.and setting parameter values. But i am getting error code 77.What is cause?
No of records to be inserted are approx 70000.So i am inserting 100 records in one query and then using addBatch() on preparedstatment 700 times i execute whole batch .
Actually it was not error code 77.it was no of updates per statement.SO Everything is working fine.