How to run multiple sql commands with SQLQuery object in java - java

I'm trying to use SQLQuery object with multiple sql commands. I need to split the query in order to get better performance.
CREATE TABLE x (
id integer,
key integer)
select *
from x, users,.......
where .......
DROP TABLE x

If your issue is creating and dropping tables, create a TEMPORARY table with drop on commit. Then when you commit your db transaction the table will be gone.
The issue is that usually you only get the last statement's results returned. If you need something else, look at wrapping with a user defined function and presenting a single tabular result set back.

Related

Batching "UPDATE vs. INSERT" Queries Against Oracle Database

Let's assume that I have an Oracle database with a table called RUN_LOG I am using to record when jobs have been executed.
The table has a primary key JOB_NAME which uniquely identifies the job that has been executed, and a column called LAST_RUN_TIMESTAMP which reflects when the job was last executed.
When an job starts, I would like to update the existing row for a job (if it exists), or otherwise insert a new row into the table.
Given Oracle does not support a REPLACE INTO-style query, it is necessary to try an UPDATE, and if zero rows are affected follow this up with an INSERT.
This is typically achieved with jdbc using something like the following:
PreparedStatement updateStatement = connection.prepareStatement("UPDATE ...");
PreparedStatement insertStatement = connection.prepareStatement("INSERT ...");
updateStatement.setString(1, "JobName");
updateStatement.setTimestamp(2, timestamp);
// If there are no rows to update, it must be a new job...
if (updateStatement.executeUpdate() == 0) {
// Follow-up
insertStatement.setString(1, "JobName");
insertStatement.setTimestamp(2, timestamp);
insertStatement.executeUpdate();
}
This is a fairly well-trodden path, and I am very comfortable with this approach.
However, let's assume my use-case requires me to insert a very large number of these records. Performing individual SQL queries against the database would be far too "chatty". Instead, I would like to start batching these INSERT / UPDATE queries
Given the execution of the UPDATE queries will be deferred until the batch is committed, I cannot observe how many rows are affected until a later date.
What is the best mechanism for achieving this REPLACE INTO-like result?
I'd rather avoid using a stored procedure, as I'd prefer to keep my persistence logic in this one place (class), rather than distributing it between the Java code and the database.
What about the SQL MERGE statement. You can insert large number of records to temporary table, then merge temp table with RUN_LOG For example:
merge into RUN_LOG tgt using (
select job_name, timestamp
from my_new_temp_table
) src
on (src.job_name = tgt.job_name)
when matched then update set
tgt.timestamp = src.timestamp
when not matched then insert values (src.job_name, src.timestamp)
;

Huge Update or Inserts into DB2 using JAVA and JPA 1.0

I have a JAVA requirement where i have 1500 records that I have to update or insert into the database.
If a record exists with userId, then update it.
If a record does not exist with userId, then Insert it.
And, if there is an error in lets say, 10th record,,,I need to get
the error code for that record.
It looks like I have 2 options using JPA 1.0
A) Fire a select to check if record exists. If yes, then fire update. If not, fire insert.
B) Fire an insert always,,,but i get an uniqe record exception, only then fire an update query..
Are there any other more efficient ways ? how can this be done with as few queries and as quick as possible ?
ENV- JAVA, JPA 1.0, DB2
You did not specify which version of DB2 you use and on which system. Anyway, check if MERGE statement is available on your DB:
LUW from 9.5.0: http://www.ibm.com/support/knowledgecenter/SSEPGG_9.5.0/com.ibm.db2.luw.sql.ref.doc/doc/r0010873.html
Z/OS from 10.0.0: http://www.ibm.com/support/knowledgecenter/SSEPEK_10.0.0/sqlref/src/tpc/db2z_sql_merge.html
Another way is to do delete + insert on every record (poor performance).
Third option is to create dynamic one delete statement with listed ID/KEY in where clause from data you are going to update, fire delete and then insert all data.
Performance of every option will depend on table specification, indexes etc.
you can write query in mysql as below
//suppose a as pk
INSERT INTO table (a,b,c) VALUES (1,2,3)
ON DUPLICATE KEY UPDATE c=c+1,b=b+1;
here update will run when record with pk as a=1 is already present
refer below link http://dev.mysql.com/doc/refman/5.7/en/insert-on-duplicate.html

How to increase the fetching time of a particular value from database from java?

I want to fetch a particular value from database in java. I used the following command in prepared statement:
Select Pname from table where pid=458;
The table contains around 50,000 rows and taking more time to fetch, please help me to get the data faster.
i used index and then i bind the variable also but it reduce the execution time only few seconds, i need more efficient. Is there any way to retrieve data faster???
Index your database table for pid, it will make the search faster.
Indexes are used to quickly locate data without having to search every row in a database table every time a database table is accessed. Indexes can be created using one or more columns of a database table, providing the basis for both rapid random lookups and efficient access of ordered records.
SQL Server
CREATE TABLE MyCustomers (CustID int, CompanyName nvarchar(50));
CREATE UNIQUE INDEX idxCustId ON MyCustomers (CustId);
References
https://msdn.microsoft.com/en-us/library/ms188783.aspx
https://technet.microsoft.com/en-us/library/ms345331(v=sql.110).aspx
Create index on field pid in your table.
Use bind variables in queries.
Use prepared statement instead of statement in Java, that will use bind variables.
pstatement = conn.prepareStatement("Select Pname from table where pid = ?");
This ensures that the SQl is pre compiled and hence runs faster.
However, you are likely to gain more performance improvement by index than bind variables .

Deleting multiple rows in a one statement

I have some trivial table in database (let say Oracle10g) and I need to implement at DAO ability to delete multiple records. The method remove() receives as a parameter an array of ids (integers).
For now I have a query string "DELETE FROM news WHERE id = ?" which I use at PreparedStatement. I simply add batch for every id from array and then perform execute on PreparedStatement.
I wonder if there any ability to perform it through one query statement, something like "DELETE FROM news WHERE id IN ?". But I cannot find how to properly set an array of integers instead of '?'.
The same question applies to Hibernate and JPA. If there any constructions to solve this ? Because now I use batch-like-way: add Query to Session on every id from array and commit transaction.
The best I've seen done is to dynamically build the String used by the PreparedStatement, inserting the proper # of ?, sequences, then use a for loop to call setInt as appropriate for each row - each row to be deleted in your case.
JPA provides a special syntax for this (can accept a Collection to populate the list of arguments), since it has to create the SQL anyway - and likely does so very similar to how I just described. Specifics as to the API calls (for both JPA and HQL) are available at Hibernate HQL Query : How to set a Collection as a named parameter of a Query? .

How can I treat a sequence value like a generated key?

Here is my situation and my constraints:
I am using Java 5, JDBC, and DB2 9.5
My database table contains a BIGINT value which represents the primary key. For various reasons that are too complicated to go into here, the way I insert records into the table is by executing an insert against a VIEW; an INSTEAD OF trigger retrieves the NEXT_VAL from a SEQUENCE and performs the INSERT into the target table.
I can change the triggers, but I cannot change the underlying table or the general approach of inserting through the view.
I want to retrieve the sequence value from JDBC as if it were a generated key.
Question: How can I get access to the value pulled from the SEQUENCE. Is there some message I can fire within DB2 to float this sequence value back to the JDBC driver?
Resolution:
I resorted to retrieving the PREVIOUS_VAL from the sequence in a separate JDBC call.
Have you looked at java.sql.Statement.getGeneratedKeys()? I wouldn't hold out much hope since you're doing something so unusual but you never know.
You should be able to do this using the FINAL TABLE syntax:
select * from final table (insert into yourview values (...) );
This will return the data after all triggers have been fired.

Categories

Resources