How to copy table from one database to another? - java

I need to take a table from one database and upload it to a different database.
So, I create two separate connection . Here is my code
Connection connection1 = // set up connection to dbms1
Statement statement = connection1.createStatement();
ResultSet result = statement.executeQuery("select * from ............. ");
Connection connection2 = // set up connection to dbms2
// Now I want to upload the ResultSet result into the second database
Statement statement2 = connection2.createStatement("insert into table2 " + result);
statement2.executeUpdate();
The above last lines do not work
How can i do this ? The bottomline is how to reuse a ready resultset
ResultSet is a ready java object . I hope there is a way add it to batch or something like this and executeUpdate , but not to write the result set to some temporary space (List, csv etc.) and the insert

The simplest way to do this is with a prepared statement for the insert. It lets you create a single statement object that can be used to run the query multiple times with different parameter values.
try (final Statement statement1 = connection1.createStatement();
final PreparedStatement insertStatement =
connection2.prepareStatement("insert into table2 values(?, ?)"))
{
try (final ResultSet resultSet =
statement1.executeQuery("select foo, bar from table1"))
{
while (resultSet.next())
{
// Get the values from the table1 record
final String foo = resultSet.getString("foo");
final int bar = resultSet.getInt("bar");
// Insert a row with these values into table2
insertStatement.clearParameters();
insertStatement.setString(1, foo);
insertStatement.setInt(2, bar);
insertStatement.executeUpdate();
}
}
}
The rows are inserted into table2 as you iterate through the results from table1, so there's no need to store the whole result set.
You can also use the prepared statement's addBatch() and executeBatch() methods to queue up all the inserts and send them to the database all at once, instead of sending a separate message to the database for each individual inserted row. But that forces JDBC to hold all the pending inserts in memory locally, which it seems you're trying to avoid. So the one-row-at-a-time inserts are your best bet in this case.

If you don't want to manually list out all the field names for every table in the database, you should be able to do this two-step process instead:
Copy the table schema using the answer in this question.
Use resultSet.getMetaData() to get the list of fields, and use that to drive a modified version of the SELECT/INSERT code in #Wyzard's answer.
I will post code here if I get it working.

Related

Sql query with bind variables execution in Jdbc

I have a sql query like this.
select "DEPT"."DEPTNO" as "DEPTNO1",
"DEPT"."DNAME" as "DNAME1",
"DEPT"."LOC" as "LOC1",
"EMP"."COMM" as "COMM1",
"EMP"."EMPNO" as "EMPNO1",
"EMP"."ENAME" as "ENAME1",
"EMP"."HIREDATE" as "HIREDATE1",
"EMP"."JOB" as "JOB1",
"EMP"."MGR" as "MGR1",
"EMP"."SAL" as "SAL1"
from "EMP" , "DEPT" where "DEPT"."DEPTNO" in (:DeptNo)
//This is the Jdbc code
Class.forName(DB_DRIVER);
dbConnection = DriverManager.getConnection(DB_CONNECTION, DB_USER, DB_PASSWORD);
Statement statment = dbConnection.createStatement();
result = statment.execute(query);//query is above sql query
When i run above query in Oracle sql developer works perfectly.But when i run it with above jdbc code it is throwing Not all variables bound exception.
How to run above query in JDBC
replace :deptno in your query with a ?.
and instead of instantiating statement use the following:
PreparedStatement stmt=con.prepareStatement(query);
stmt.setInt(1,deptno); //1 is for the first question mark
where deptno holds the value for which you want to execute the query.
Through PrepredStatement interface we can use parametrized query which is compiled only once and has performance advantage in comparison to the Statement interface.
You created a Query with bind variable and you never set it.
Use OraclePreparedStatement and its method setStringAtName()
statement.setStringAtName("DeptNo","<<your Value>>");
If not OraclePreparedStatement, you can just put it as ?1 in your Query string
and use,
statement.setString(1,"<<your Value>>");
If in case, you don't know how many bind variables you get, you have capture the bind variables in a map and prepare a list and set it accordingly!
Else your requirement is unachievable!
Get the query dynamically from the report.
From this query we need to split querystring to get number of bind variables and placing those bind variables in a HashMap.HashMap is like
{DeptName =1, Job =1, DeptNo =1}
From this hashmap,need to replace the query bind variable with ?.For this we need to do like
bindkey = entry1.getKey().toString();
String bindkeyreplace =":".concat(bindkey).trim();
String bindkeyreplacestring = "?";
query = query.replace(bindkeyreplace, bindkeyreplacestring);
Then we will get dynamic query coming from the report with ? instead of :bindvariable
PreparedStatement prestmt = dbConnection.prepareStatement(query);
for (int i = 0; i < bindParamMap.size(); i++) {
prestmt.setInt(i + 1, 0);//Setting default value to check the query is running successfully or not
}
result = prestmt.execute();
If in case, we don't know how many bind variables we get then this approach is running successfully for me.
Use this syntax,EMP.DNAME as DNAME1. I mean your dot and as must be inside the double quotes.
The variable DeptNo must be bound to a value before you execute the statement like below.
DriverManager.getConnection(DB_CONNECTION, DB_USER, DB_PASSWORD);
Statement statment = dbConnection.createStatement();
//Bind deptno to a value
statment.setParameter("DeptNo",5);
result = statment.execute(query);
You must set values for all the variables in your prepared statement othwerise you cannot execute the statement. If you receive the query to execute itself as an input then you should also get the parameters and its values also as input. Something like below
public <returnType> executeQuery(String queryStr, Map<String,Object> params) {
//Code to create connecitno and statment from queryStr.
//Bind deptno to a value
for(int i=0;i<params.size(),i++) {
//Get entry set from map
statment.setParameter(entryset.getKey(),entryset.getValue());
}
result = statment.execute(query);
//return or work on the result
}

What method to create, in order to delete the rows of information from the database?

This is my first time making an application and I am quite new with connecting the netbeans IDE to the MySQL database. I have a delete button in a Jpanel, and I want to be able to delete added rows. At the moment I can delete the added rows but they are of course not delete within the SQL DB which means they will remain there when I restart the application.
This is what I have to delete the rows so far
private void removeProductBtnActionPerformed(java.awt.event.ActionEvent evt) {
// TODO add your handling code here:
DefaultTableModel model = (DefaultTableModel) this.productTable.getModel();
int[] rows = productTable.getSelectedRows();
for(int i=0;i<rows.length;i++){
model.removeRow(rows[i]-i);
// If I highlight the rows and delte the, they are still in the SQL database.
//How to remove the complete data from the row in the SQL database? What method to write?
String sql = "DELETE FROM Product WHERE ProductID = ?";
Below I have my query to put it inside the database. (so you know what variables I am using)
public ResultSet insertQuery(String query) {
ResultSet result = null;
try {
Statement statement = connection.createStatement();
statement.executeUpdate(query);
result = statement.getGeneratedKeys();
} catch (SQLException e) {
System.err.println(e);
}
return result;
You have a '?' in your sql but you aren't using prepared statement.
For example's sake try:
String sql = "DELETE FROM Product WHERE ProductID = " + rows[i]-i
Question marks are used for prepared statements in java which (among other things) is used for sanitising inputs. Once you get the rest of your code working you should investigate it.

Resultset in java is not working according to my expectations

dbStatement = con.createStatement();
dbResult = dbStatement.executeQuery("SELECT Vendor_Code FROM temp ORDER BY status ASC ");
while (dbResult.next())
{
VendorCode=dbResult.getString("Vendor_Code");
System.out.println(VendorCode);
dbStatement.executeUpdate("INSERT INTO temp1 VALUES ('"+VendorCode+"')");
}
In the above code I am selecting a list of vendor code in the ascending order of their status,it works properly if I don't add:
dbStatement.executeUpdate("INSERT INTO temp1 VALUES ('"+VendorCode+"')");
into the while loop. If I add this I'm getting result as only the first value which is in the sorted list and also it's getting inserted into the temp1 table...
I am using Java swing and MySQL in NetBeans. Any idea please why this is happening?
If I do the above code in other way as,
dbStatement = con.createStatement();
dbInsert = con.createStatement();
dbResult = dbStatement.executeQuery("SELECT Vendor_Code FROM temp ORDER BY status ASC ");
while (dbResult.next())
{
VendorCode=dbResult.getString("Vendor_Code");
dbResult = dbInsert.executeQuery("SELECT Bid_No,Vendor_Name,Vendor_Address,Amount,Tax_Percentage,Amount_Aftertax,Expected_Deliverydate,Vendor_Code FROM purchase_bid where PE_Number='"+penumber+"' AND Vendor_Code='"+VendorCode+"' ");
while(dbResult.next())
{
Bid_Number=dbResult.getString("Bid_No");
vendor_name=dbResult.getString("Vendor_Name");
vendor_address=dbResult.getString("Vendor_Address");
Amount=dbResult.getString("Amount");
tax=dbResult.getString("Tax_Percentage");
date2=dbResult.getString("Expected_Deliverydate");
Amount_Aftertax=dbResult.getString("Amount_Aftertax");
venCode=dbResult.getString("Vendor_Code");
date3=date2.split("-");
String day="";
String month="";
String year="";
day=date3[2];
month=date3[1];
year=date3[0];
date=day+"-"+month+"-"+year;
addtoCart();//for displaying it in jTable
}
}
It does not take VendorCode in ascending order for retrieving values from purchase_bid table..Then it again takes first sorted value and nothing is displayed in jTable.
You can only use one result set per statement at a time (for a query, update etc.). See the doc:
By default, only one ResultSet object per Statement object can be open
at the same time
I would either:
load all your vendor codes into a collection, and then perform an update using a new statement/update
perform all the required actions within one SQL update statement (may be preferable for performance and transactional reasons. All the work will be contained in the database instance)
EDIT: Amended following EJP's comment below.
You should only use the statement instance for one operation. So calling the executeUpdate-method erases the ResultSet obtained by the executeQuery-method.
Create a second statement, so that:
dbStatement = con.createStatement();
dbInsert = con.createStatement();
dbResult = dbStatement.executeQuery("SELECT Vendor_Code FROM temp ORDER BY status ASC ");
while (dbResult.next())
{
VendorCode=dbResult.getString("Vendor_Code");
System.out.println(VendorCode);
dbInsert.executeUpdate("INSERT INTO temp1 VALUES ('"+VendorCode+"')");
}
If you're not just testing and you actually want to bulk insert the Vendor_Code from temp to temp1, try using INSERT ... SELECT
dbInsert = con.createStatement();
dbInsert.executeUpdate("INSERT INTO temp1 SELECT Vendor_Code FROM temp");
See the official MySQL documentation for further details on this type of INSERT:
http://dev.mysql.com/doc/refman/5.1/en/insert-select.html

Max value from auto commit false table

My problem is i have set a table auto commit false. I need to get the max id from that table(the currently inserted value of auto increment id). But i am getting the id of the previous committed process. Is it possible to get the value
My real problem is i need to insert into table some values, And need to take the id of the last inserted record from the first table and insert it to the second. The second insertion includes some image upload as well(as part of the code). so it take some delay or can have exceptions. I need to undo all insertions(both in the first and second) by occurring any exceptions. I tried to use commit-roll back method for this. But its not properly working as i mentioned above. main portion of my code is written below
try
{
//getting connection and setting auto commit false
dbHandler dbGetConnect=new dbHandler();
Connection conRegPlot=null;
conRegPlot=dbGetConnect.getconn();
conRegPlot.setAutoCommit(false);
String qryInsertPlot="INSERT INTO property_table(name,message,owner,locality,lattitude,longitude,country,state,city,type,catagory,created,modified,creted_date,zoompoint,mob_no,title,img_path,expire_date,lease_term) VALUES('none','"+description+"','"+sessionUserId+"','"+locality+"','"+lattitude+"','"+longitude+"','"+country+"','"+state+"','"+city+"','"+type+"','"+catagory+"',NOW(),NOW(),CURDATE(),'"+zoom+"','"+mob_no+"','"+title+"','NOT IN USE',"+expireDate+",'"+termsAndConditions+"')";//insertion into the first table
Statement stCrs=conRegPlot.createStatement();
int resp=stCrs.executeUpdate(qryInsertPlot);
String qryGetMaxProperty="SELECT MAX(l_id)"+
" FROM property_table"+
" WHERE stat='active'"+
" AND CURDATE()<=expire_date";
propertyId1=dbInsertPropert.returnSingleValue(qryGetMaxProperty);// get the max id
String qryInsertImage="INSERT INTO image_table(plot_id,ownr_id,created_date,created,modified,stat,img_path) VALUES('"+propertyId1+"','"+sessionUserId+"',CURDATE(),NOW(),NOW(),'active','"+img_pth+"')";
Statement stImg=conRegPlot.createStatement();
stImg.executeUpdate(qryInsertImage);// inserting the image
conRegPlot.commit();
}
catch(Exception exc)
{
conRegPlot.rollback();
}
finally{
conRegPlot.close();
}
Since
And need to take the id of the last inserted record from the first
table and insert it to the second.
You could the use of the new JDBC 3.0 method getGeneratedKeys() for get the generated ID. In ahother hand, you should use PreparedStatement for avoid SQL Injection.
PreparedStatement ps = null;
try {
conn = getConnection();
ps = conn.prepareStatement(myQuery, PreparedStatement.RETURN_GENERATED_KEYS);
ps.setInt(1, anInteger);
...
int rows = ps.executeUpdate();
if (rows == 1) {
ResultSet keysRS = ps.getGeneratedKeys();
if (keysRS.next())
int id = keysRS.getInt(1) // Get generated id
For MySQL, see more in http://dev.mysql.com/doc/refman/5.1/en/connector-j-usagenotes-last-insert-id.html#connector-j-examples-autoincrement-getgeneratedkeys

SQL - how to return multiple rows with one SQL query?

I have a managed bean which makes SQL queries to Oracle database. This is just very simple example how I make SQL queries. This is the table structure:
GLOBALSETTINGS
---------------------------------
SessionTTL VARCHAR2(40 BYTE)
MAXACTIVEUSERS NUMBER
ACTIVEUSERS VARCHAR2(20 BYTE)
I use this table just to store application settings. In the example listed below I can fetch just one string with one SQL statement. I want with SQL query to fetch the content of the three rows - SessionTTL, MAXACTIVEUSERS, ACTIVEUSERS. Is it possible?
public String CheckUserDB(String userToCheck) throws SQLException {
String storedPassword = null;
String SQL_Statement = null;
if (ds == null) throw new SQLException();
Connection conn = ds.getConnection();
if (conn == null) throw new SQLException();
try {
conn.setAutoCommit(false);
boolean committed = false;
try {
SQL_Statement = "SELECT Passwd from USERS WHERE Username = ?";
PreparedStatement passwordQuery = conn.prepareStatement(SQL_Statement);
passwordQuery.setString(1, userToCheck);
ResultSet result = passwordQuery.executeQuery();
if(result.next()){
storedPassword = result.getString("Passwd");
}
conn.commit();
committed = true;
} finally {
if (!committed) conn.rollback();
}
}
finally {
conn.close();
}
return storedPassword;
}
P.S I want the content of the rows.
I'm hoping I understand what you are asking for, but I fear I don't as it seems too simple, but anyway...
I think you want the contents of 3 columns, not rows. And yes you can, you just specify the columns you want returned in your SQL statement:
SELECT SessionTTL, MAXACTIVEUSERS, ACTIVEUSERS FROM GLOBALSETTINGS WHERE (condition)...
you can also use * as a shortcut for all columns iof you don't want to explicitly specify them:
SELECT * FROM GLOBALSETTINGS WHERE (condition)...
Some background reading on SQL syntax might be useful
If I read this correctly (sorry if mistaken), all you want to do is change your SQL command to select ALL COLUMNS in your database table.
To do so:
string SqlAll = #"SELECT Database.SessionTTL, Database.MAXACTIVEUSERS, Database.ACTIVEUSERS FROM Database";
This will retrieve ALL columns in the database. You can also have conditional statements in your queries when you want to filter for logical reasons, such as TOP 20 to get the first 20 results from the result set.
If you like to return multiple lines with one sql query, you may want to look into ArrayList as you need a loop, where the code would go through your records and match and find all possible results until the end of the records list.

Categories

Resources