I am trying to have batch update query However each update Query is different but running on the same table. The Where clause is the same.
For example :
TABLE : Column A,B,C,D,ID
update A where ID=1
update B,C where ID=1
update D,B where ID=1 and so on ... ( all the combinations of A,B,C,D)
I have investigated spring jdbc (JDBCTemplate and JDBCNamedParameter ) and QueryDsl but its not possible to have such updates.
Is there any other method by which such update as batch is possible ? I have stick to Spring-JDBC.
Do you want to use a prepared statement passing in the arguments for each update? If so, it's not possible to do this as a batch. You could batch multiple statements, but then you would have to create these statements without using placeholders for the arguments. In this scenario you would use the int[] JdbcTemplate.batchUpdate(String[] sql) method (http://docs.spring.io/spring/docs/4.0.3.RELEASE/javadoc-api/org/springframework/jdbc/core/JdbcTemplate.html#batchUpdate-java.lang.String:A-).
It's not possible to batch different prepared statements using the JDBC API. You can batch individual statements without arguments (http://docs.oracle.com/javase/7/docs/api/java/sql/Statement.html#addBatch(java.lang.String)) or batch multiple sets of arguments for a prepared statement (http://docs.oracle.com/javase/7/docs/api/java/sql/PreparedStatement.html#addBatch()), but the SQL statement would have to be the same for all sets of arguments.
You can still wrap multiple update calls in a transaction, but there would be multiple roundtrips to the database server.
You can wrap your update with a stored proc, then you can batch round trips to the database.
Inside the stored proc you'll need to generate the update based on the arguments passed in. So you could test for null, or pass a separate flag for each column. If the flag is set, then generate SQL that updates that column.
Related
Because I have insert statement which should be happen only if update statement executed fine, otherwise proceed to other set of insert and update query inside batch and do the same
The REST call is sending the branchId and emplId to this exec-sql-file method. I am passing these as a parameter. I am not able to execute the SQL statement when I pass branch_id = #branchid and empl_id = #emplid. But when I hardcode the branch_id = 'BR101' and empl_id = 123456 then it is working. Any suggestion how to get the branch_Id and empl_Id in my some-statements.sql?
(defn exec-sql-file
[branchid emplid]
(sql/with-db-connection (db-conn)
(sql/db-do-prepared conn
[branchid emplid (slurp (resource "sql/some-statements.sql"))])))
some-statements.sql have this query
DELETE from customer where branch_id = #branchid and empl_id = #emplid;
I am executing this from REPL as
(exec-sql-file "BR101" 123456)
I grab the code snippet from the below post.
Is it possible to patch load SQL statements from a file using clojure.java.jdbc?
There is no simple way to do this as your approach requires that you have to provide parameters to multiple SQL statements in one run. Another issue is that Java's PreparedStatement (used under the hood by clojure.java.jdbc) doesn't support named parameters, so even if parameters to multiple SQL statements done using a single prepared statement would have to be provided for every placeholder (?).
I would suggest following solutions:
use multiple prepared statements (so separate clojure.java.jdbc/execute! calls) for each of the SQL statement you want to execute wrapped in a single transaction (each SQL could be read from a separate file). You could also use some helper library like YeSQL to make loading your SQL statements from external files and exposing them as functions you could call as ordinary Clojure functions. It would be simple but if you change the number of statements you would like to execute, then you need to change your code
create a stored procedure and call them from Clojure providing the parameters - this will define an interface for some DB logic which will be defined on the DB side. Unless you change the interface of your stored procedure you can modify its implementation without changing your Clojure code or redeployment
implement your own logic of interpolating named parameters into your "multistatement" SQL file. The issue is to appropriately escape parameters' values so your code is not vulnerable to SQL injection. I would discourage this solution.
I am planning to maintain logic for a derived field in a look up table and thinking of running dynamic sql statements real time.
for example , if field company_type is derived based on the following logic
case when substr(company_code,1,3)='XYZ' then substr(comapny_code,4,6)
when substr(company_code,1,3)='ABC' then substr(company_code,7,9)
else substr(company_code,1,3) end;
to avoid code changes whenever a new case is provided by business i want to maintain the logic in a look up table like following
order src_filed src_value
--------------------------------------------------------------
1 substr(company_code,1,3)='XYZ' substr(4,6)
2 substr(company_code,1,3)='ABC' substr(7,9)
3 substr(1,3)
now based on the data in look up table , i want to be able to generate case statement dynamically and to be able to run the case statemnent. Note that i need to run that dynamic sql as part of another sql where i query source tables that has source fields.
This feature doesn't exist yet in Vertica. Hopefully in a future version. Easiest method is to write a script to execute the sql via vsql or jdbc.
I have a requirement of updating a table which has about 5 million rows.
So for that purpose i want to create batch statements in java and update as a bulk operation.
Righht now I have 100 batches aand it works fine.But when i increase the number of batches over hundred i get an exceptio as : com.sybase.jdbc2.jdbc.SybBatchUpdateException: JZ0BE: BatchUpdateException: Error occurred while executing batch statement: Message empty.
How can i have more batch statements in my CallableStatement object.
Not enough reputation to leave comments...but what types of statements are you batching? how many of these rows are you updating? Does the table have a primary key? How many columns in the table, and how many of those columns are you updating?
Generic answer:
The JDBC framework in sybase is extremely fast. You might at least consider writing a simple procedure that receives the primary key (or other) information you're using to identify the row, along with the new values that row will be updated to as input variables. this procedure will update a single row only.
Wrap this procedure in it's own java method that handles the callablestatement, register your out error number and error message params, etc.
Then you can loop through whatever constructs you're using now to update data, and use the same java method to call the procedure to update the values row by row.
Again, i don't know the volume of what you're trying to do...but I do know if you're trying to do single row updates, this will be VERY fast.
does statement object contain the session id the database returns for the current session? What does a resultset
contain?
To the best of my knowledge, no, Statements do not have session IDs. It seems like the Java API specifications for the Statement class backs that up. Basically, Statements are used to execute SQL statements by specifying a SQL query through the execute method.
A ResultSet is used to retrieve results which are returned by executing a query via a Statement or PreparedStatement.
The JDBC(TM) Database Access trail of The Java Tutorials contains some information on these topics. The following sections may be of interest:
Lesson: JDBC Basics
Updating Tables
Retrieving Values from Result Sets