How to bulk insert in db if another insert succeeds? - java

I have to insert ~40K records in 2 tables(say table1 & table2) in the database.
The insert in table2 is conditional. A record should be inserted in table2 if and only if a record is inserted in table1 successfully.
Can this be done in batch? I'm using JDBC driver. I'm using Oracle 10g XE.
What is the best approach to do this? Should I go for db pooling with multi-threading?

The executeUpdate method will return the number of rows affected by your statement. Could use this as a comparison to check it had executed successfully.

My suggestion is perform the business logic for the operation as close to the data as possible. This will mean having a PL/SQL procedure to act as an API for the functionality you wish to perform.
This will make your code trivial; a simple call to the database procedure which will return something giving you the result.
All the logic applied to the data is performed by code designed almost exclusively to manipulate data. Unlike Java which can manipulate data but not as well as PL/SQL. Incidentally it is also likely to be much faster.(this presentation on Youtube is very informative, if a little long - https://www.youtube.com/watch?v=8jiJDflpw4Y )

Related

Get inner SELECT result as ResultSet from INSERT INTO SELECT statement in mySQL Java

I have 2 DBs, Database A and Database B.
What I want to achieve:
build records from Database A and insert them to Database B
Process those records in my java app
What I'm currently doing:
I use two separate queries:
For (1) I use INSERT INTO ... SELECT ...
For (2) I perform another SELECT.
My solution works but it isn't optimal since I'm getting the records from Database A twice (instead of just one time).
Is there a way to execute the INSERT INTO ... SELECT ... and get the inner select result as a ResultSet?
I know I can perform only a SELECT and then insert the records in a batch, but thats a bit cumbersome and I want to find out if there's a cleaner solution.
Your cleaner solution look more cumbersome than simple read and write operation.
As you have to manipulate data in database B. You simply do this
Read Data from A to your app
Process data
Write data to B from your app
Then you have singe read single write and is simple.
You can not gain the result of INSERT INTO as Result set as this is INSERT statement
Sadly, I do not think that this is possible. What you are trying to achieve are two distinct operations i.e. an INSERT and a SELECT. However you cut it you are still going have to do at least one INSERT and one SELECT.
use this for two database
INSERT INTO Database2 (field1,field2,field3){
SELECT * FROM Database1;);
Both the database have the same field name.

How can I bulk insert?

I want to insert data to TERADATA with jdbc.But it is slow. How can I make it faster?
I wrote this code:
connection_tera= DriverManager.getConnection
(
"jdbc:teradata://192.168.x.xx/database=DBC,tmode=ANSI,charset=UTF8","dbc","dbc"
);
stmt_tera = connection_tera.prepareStatement("insert into a.b values(?)");
//some code here to start while loop
stmt_tera.setObject(i,reset.getobject(i));
stmt_tera.addBatch();
if(addedBatchNumber%100==0)
stmt_tera.executeBatch();
connection_tera.commit();
stmt_tera.clearBatch();
//some code here and finish while loop
Should I add paramater like TYPE=FASTLOAD to connection string? or something else?
If you are loading to an empty table I would consider using JDBC FastLoad. For more details on the performance of JDBC to insert data into a Teradata table please refer to the following article on the Teradata Developer Exchange: Speed up your JDBC/ODBC Applications
If your table is not empty, it may make sense to load the data to a staging (intermediate) table that is empty first. Then use the ANSI MERGE operation to apply the INSERT/UPDATE logic to the target table. The MERGE operation will perform faster than the traditional INSERT and UPDATE statements because the operation works at the block level instead of row level. In some instances you can even avoid spooling the source data before the data is applied to the target table.
Here is a collection of sample Teradata JDBC Driver programs. Programs 205 through 209 are examples of using FastLoad.
Additionally you can also consider another side of the coin..Meaning you can think of performing multiple row insert with single query
insert into table1 (First,Last) values ('Fred','Smith'),
('John','Smith'),
('Michael','Smith'),
('Robert','Smith');
The benefits are
Connecting/interacting with database is an expensive operation. Say you have to insert 100 rows using your code so you would write your application in such a way to fire 100 quires( 100 db interactions ).. Instead of this, build your sql query as mentioned above and try insert and check the performance.
You are avoiding n number of database interactions.
Insert operation is seamlessly faster if you do like this.. This has been widely adopted technique to restore/import databases.
Hope this will be helpful..
Cheers!
Cheers!
If I'm reading this correctly, you are executing and committing a batch that has only one insert statement in it - I don't think that is your intention ( or, if it is, I think you are misunderstanding how batches are expected to be used )
Seems like you need to have an inner loop that adds an arbitrary number of statements to the batch which you then submit via executeBatch()

Select and update in the same PL/SQL query

I have a producer thread in Java pulling items from an Oracle table every n milliseconds.
The current implementation relies on a Java timestamp in order to retrieve data and never re-retrieve them again.
My objective is to get rid of the timestamp pattern and directly update the same items I'm pulling from the database.
Is there a way to SELECT a set of items and UPDATE them at the same time to mark them as "Being processed"?
If not, would a separate UPDATE query relying on the IN clause be a major performance hit?
I tried using a temporary table for that purpose, but I've seen that performance was severely affected.
Don't know if it helps, but the application is using iBatis.
If you are using oracle 10g or higher, you can use the RETURNING clause of the update statement. If you wish the retrieve more than one row you can use the BULK COLLECT statement.
Here is a link to some examples;
http://psoug.org/snippet/UPDATE-with-RETURNING-clause_604.htm

JDBC insert or update practice

I need to insert a record to table if the record doesn't exist, and to update a record if the record exists in the table.
Of course, I can write:
p-code:
SELECT * FROM table1 WHERE id='abc' by JDBC
if(exists)
UPDATE table1 SET ... WHERE id='abc' by JDBC;
else
INSERT INTO table1... by JDBC;
However, I don't think the code is elegant.
Alternatively, I can also write it in this way:
p-code:
int row = Statement.executeUpdate("INSERT INTO table1...", 2);
if(row==0)
update table1 SET ... WHERE id='abc' by JDBC;
Do you think the latter way is better and faster? Thanks!
EDIT: in MYSQL
It depends on what type of database your are using and whether or not you can take advantage of database specific features. MySQL for instance lets you do the following:
INSERT INTO territories (code, territory) VALUES ('NO', 'Norway')
ON DUPLICATE KEY UPDATE territory = 'Norway'
However, the above is not standard (SQL-92) compliant. That is, it will most likely not work on all databases. In other words, you would have to stick with the code as you have written it. It might not look that elegant, but it is probably the most safe solution to go with.
You might want to look at using the DBMS to do the check within a single statement i.e. use the SQL EXISTS condition: WHERE EXISTS or WHERE NOT EXISTS
Maybe the database you are using has an insert or update feature which solves this automatically for you. In DB2 you can use MERGE INTO for example. See here
This is probably the reason to switch to one of popular ORM solutions (Hibernate, Toplink, iBatis). These tools "know" various SQL dialects and optimise your queries accrodingly.

Retrieving data from DB

I have this table in oracle and i need to retrieve two columns from the table desc_data
eg:
select ticket_id, date_logged from desc_data;
I would have around 10,000 records in this table, so if I do this operation from java and perform some operations in java by putting these values in a list and then based on some conditions filter data and insert back into some other table, would it be possible and if it's possible would it be an overhead?
I think better to use a stored procedure in database and just call it from java. But what you consider is a possible solution too.
It depends on what type of filtering you wish to do on your 10000 records. If the filtering is simple, such as filtering the records in a date range, then you can achieve that just using SQL. If your processing is more complex, then you could also use an stored procedure. As you are running on Oracle these can be written in Java. See here for an example.

Categories