I am trying to update 2 tables at the same time where the inserted index of the first should be inserted into the 2nd table.
The sql looks like this:
DECLARE #nrTable table (TXT_nr int)
IF NOT EXISTS (SELECT txt FROM tbl1 WHERE txt = (?))
INSERT INTO tbl1 (txt, new) OUTPUT INSERTED.nr INTO #nrTable VALUES((?), 1)
IF NOT EXISTS (SELECT txt FROM tbl1 WHERE txt =(?))
INSERT INTO tbl2 (TXT_nr, field1, field2)
VALUES((SELECT TXT_nr FROM #nrTable), (?), (?))
WHERE field3 = (?) AND field4 = (?)
I am trying to accomplish this using
this.jdbcTemplate.batchUpdate(sql, batch);
simply concatenating the lines in java using basic strings. This seems to only execute the first statement, though.
Now the reason I donĀ“t want to do this transactionally is that I would have to do it using a loop just inserting one batch-object at a time, because of the ouput-clause. This would result in loads of calls to the sql-server.
Is there any known way to accomplish something like this?
You can't use batchupdate in this way. Please refer to this document http://tutorials.jenkov.com/jdbc/batchupdate.html
And to achieve your goal, if you are using a sequence in sql, then you need to get the new value in java and store it in your query. Like this :
long id = jdbcTemplace.queryForObject("select sequence_name.nextval from dual",Long.class);
Related
I have an update/insert SQL query that I created using a MERGE statement. Using either JdbcTemplate or NamedParameterJdbcTemplate, does Spring provide a method that I can use to update a single record, as opposed to a Batch Update?
Since this query will be used to persist data from a queue via a JMS listener, I'm only dequeuing one record at a time, and don't have need for the overhead of a batch update.
If a batch is the only way to do it through Spring JDBC, that's fine... I just want to make certain I'm not missing something simpler.
You can use a SQL MERGE statment using only a one row query containing your parameters.
For example if you have a table COMPANYcontaing IDas a key and NAMEas an attribute, the MERGE statement would be:
merge into company c
using (select ? id, ? name from dual) d
on (c.id = d.id)
when matched then update
set c.name = d.name
when not matched then insert (c.id, c.name)
values(d.id, d.name)
If your target table contains the parametrised key, the name will be updated, otherwise a new record will be inserted.
With JDBCTemplate you use the update method to call the MERGEstatement, as illustrated below (using Groovy script)
def id = 1
def name = 'NewName'
String mergeStmt = """merge into company c
using (select ? id, ? name from dual) d
on (c.id = d.id)
when matched then update
set c.name = d.name
when not matched then insert (c.id, c.name)
values(d.id, d.name)""";
def updCnt = jdbcTemplate.update(mergeStmt, id, name);
println "merging ${id}, name ${name}, merged rows ${updCnt}"
Just use one of update methods, for example this one: JdbcTemplate#update instead of BatchUpdate.
Update updates a single record, batchUpdate updates multiple records using JDBC batch
I have a query which I am trying to test. The query should update the data if it finds data in the table with existing primary key. If it doesn't then insert into the table.
The Primary key is of type int and in the properties I can see Identity is set to "True" which I assume it means that it will automatically set the new id for the primary if it is inserted.
MERGE INTO Test_table t
USING (SELECT 461232 ID,'Test1-data' Fascia FROM Test_table) s
ON (t.ID = s.ID)
WHEN MATCHED THEN
UPDATE SET t.Fascia = s.Fascia
WHEN NOT MATCHED THEN
INSERT (Fascia)
VALUES (s.Fascia);
The issue here is this query doesn't work and it never inserts the data or updates. Also, query gets compiled and I don't get any compilation error
Also the reason I want this query is to work because then I will use Java prepared statement to query the database so I am assuming I can do
SELECT ? ID,? Fascia FROM Test_table
So that I can pass the values with set methods in java.
Please let me know if there is something wrong in my query.
You are selecting from the target table as your source.
You either need to remove your FROM Test_table or have at least 1 row in Test_table prior to your merge.
rextester demo: http://rextester.com/XROJD28508
MERGE INTO Test_table t
USING (SELECT 461232 ID,'Test1-data' Fascia --FROM Test_table
) s
ON (t.ID = s.ID)
WHEN MATCHED THEN
UPDATE SET t.Fascia = s.Fascia
WHEN NOT MATCHED THEN
INSERT (Fascia)
VALUES (s.Fascia);
I need to insert data from excel to database which looks:
Id Name Phone Joining Date Subject
1 A 11111 14-Mar-2001 Cse
2 B 22222 25-Dec-2016 IT
3 C 33333 12-Dec-2011 ECE
If I have to perform batch insert in a single table then I am able to do it using spring jdbctemplate(batchUpdate(...)).
But I want it to insert data in multiple tables e.g. 1st 3 columns in Table1, next 2 in Table2, next n in table3 like this way.
For reading data I am using POI API and after extracting data m keeping it in List of Map object which looks:
allObj=[{0=1.0, 1=A, 2=11111.0, 3=2001-3-14 0:0:0, 4=Cse}, {0=2.0, 1=B, 2=22222.0, 3=2016-12-25 0:0:0, 4=IT}, {0=3.0, 1=C, 2=33333.0, 3=2011-12-12 0:0:0, 4=ECE}]
How to perform this tasks? not asking full solution but a hint. Thanks
If coding is required then inform I am not posting it as it is lengthy and common.
EDITED:
Few didn't understand the Question!
I think u know batch update. I am using JdbcTemplate of spring.
suppose I have table T1 as:
Id|Name|Phone|Joining Date| Subject in Database(using MYSQL)
Now, I have an excel file with the corresponding values.I can read it and batch insert it into database by JdbcTemplate in that table.
But Now I have two table as T1: Id|Name|Phone
and T2: Joining Date| Subject
I have the same excel file.
NOW my question comes into the frame.
How to insert the values in two tables? If you get the question kindly remove your -ve vote.
LOAD DATA LOCAL INFILE
'C:\\temp\\file.csv'
INTO TABLE table_name
FIELDS TERMINATED BY ',' OPTIONALLY ENCLOSED BY '"'
LINES TERMINATED BY '\r\n'
IGNORE 1 LINES
(#col1,#col2)
set
column1 = #col1,
column2 = #col2;
Above query for table1, run same for other tables by changing column_names accordingly.
I am trying to build a query using jOOQ, this is my test code:
DSLContext create = DSL.using(SQLDialect.DERBY);
String query = create.select().from(TABLE).limit(1).offset(0).getSQL()
I get as query:
select field1, field2...fieldN etc from TABLE offset ? rows fetch next ? rows only
the problem is ? in ? rows fetch next ? rows only it seems to ignore the values that i used in limit and offset to build the query, why?
I am trying to select the first row from the results and I am using jooq 3.4.1
Thanks for the help
Query.getSQL() returns your SQL string with ? as placeholders for your bind variables. The idea is that you can feed this statement to a PreparedStatement and then explicitly bind all variables, which are available through Query.getBindValues().
You can also have jOOQ inline all your bind variables, by calling Query.getSQL(ParamType) as such:
String sql = query.getSQL(ParamType.INLINED);
I've a requirement where I need to pull out data from database.
The query is-
SELECT e.Data AS EntityBlob, f.Data AS FpmlBlob
FROM [Trades.InventoryRecord] ir, EntityBlob e, FpmlBlob f
WHERE %s AND uid = e.uid AND uid = f.uid
Here %s is the predicate after where clause which user will input from an html form.
User input will be in this form :
1. TradeDate = '2013-04-05' AND IsLatest = 'TRUE'
2. StreamId= 'IA0015'
3. The query may have IN clause also
Now when this query is rendered I get exception ambigous column streamId or ambigous column IsLatest, as these columns exists in more than one table with same name. So to remove this ambiguity I need to modify the query as - ir.IsLatest or ir.StreamId
To do so by java code, I need to first parse the predicate after where clause, extract column names and insert table name alias- 'ir' before each column name so that the query becomes -
SELECT e.Data AS EntityBlob, f.Data AS FpmlBlob
FROM [Trades.InventoryRecord] ir, EntityBlob e, FpmlBlob f
WHERE ir.TradeDate = '2013-04-05' AND ir.IsLatest = 'TRUE' AND uid = e.uid AND uid = f.uid
what is the best way to parse this predicate, or if there is any other way I can achieve the same result?
My answer to this question is to not parse the user input - there is far too much that can go wrong. It would be a lot better to have a UI with drop downs and buttons for selecting equality, inequality, ranges, in statements, etc. It may seem like more work, but protecting yourself from a SQL injection attack is even more. And even if you are not concerned about malicious SQL injection, then the user still has to get every thing exactly right, or the statement fails.