I have a MySQL database and a H2 database.
I have a resultSet from a SELECT to MySQL.
Now I want to insert each row of this resultSet into a H2 db table
I've tried this.
// Return records filtered
ResultSet filter = stmt.executeQuery(query);
// Create table filterName in H2
ResultSetMetaData rsMetaData = filter.getMetaData();
query = "CREATE TABLE " + filterName + "(";
ArrayList<String> cols = new ArrayList<String>();
for(int i = 1; i < rsMetaData.getColumnCount(); i++) {
cols.add(rsMetaData.getColumnName(i));
query = query + rsMetaData.getColumnLabel(i) + " " +
rsMetaData.getColumnTypeName(i) + "(" + rsMetaData.getColumnDisplaySize(i) + ") NOT NULL, ";
}
query = query + ");";
String queryDel = "DROP TABLE IF EXISTS " + filterName + ";";
stmtH2.executeUpdate(queryDel);
stmtH2.executeUpdate(query);
query = "INSERT INTO " + filterName + " VALUES (";
// Insert into H2 table
while(filter.next() ) {
for(int i = 0; i < cols.size(); i++) {
if(i != cols.size()-1)
query = query + filter.getString(i+1) + ", ";
else
query = query + filter.getString(i+1) + ")";
}
}
It is working, but when number of rows increase this is very slow.
Is there another way to insert each row into a H2 db table?
Related
Those are the SQL tables I am taking the data from
String sql = "CREATE TABLE IF NOT EXISTS term_index (\n"
+ " term_id integer PRIMARY KEY AUTOINCREMENT ,\n"
+ " term text ,\n"
+ " multiterm integer \n"
+ ");";
execute(sql);
sql = "CREATE TABLE IF NOT EXISTS doc_term (\n"
+ " term_id integer ,\n"
+ " wiki_id text ,\n"
+ " section text ,\n"
+ " freq integer ,\n"
+ " tfidf double ,\n"
+ " cvalue double ,\n"
+ " rake double ,\n"
+ " PRIMARY KEY (term_id, wiki_id, section) \n"
+ ");";
execute(sql);
This is the SQL statement to take the termIDs from the tables above
/**
*
* #param wikiID
* #return
*/
public HashSet<Integer> getWholeDocumentTermIDs(String wikiID) {
HashSet<Integer> termIDs = new HashSet<Integer>();
String sql= "SELECT term_id FROM doc_term WHERE wiki_id = ?";
try {
PreparedStatement stmt = conn.prepareStatement(sql);
stmt.setString(1,wikiID);
ResultSet rs = stmt.executeQuery();
while (rs.next()) {
String sql2= "SELECT term_id, multiterm FROM term_index WHERE term_id = ?";
PreparedStatement stmt2 = conn.prepareStatement(sql2);
//System.out.println(rs.getInt("term_id"));
int term_id = rs.getInt("term_id");
if(term_id != 0) {
stmt2.setInt(1,term_id);
ResultSet rs2 = stmt2.executeQuery();
int multiterm = rs2.getInt("multiterm");
if(multiterm == 0) {
termIDs.add(term_id);
}
rs2.close();
}
}
rs.close();
} catch (SQLException e) {
System.out.println(e.getMessage() + "in getWholeDocumentTermIDs");
}
return termIDs;
}
The function getWholeDocumentTermIDs(String wikiID) is called 30 k times, meaning for 30 k wikiIDS, so when executing this, steadily more and more RAM is used by my IDE, starting at roughly 1,3 GB to later up to 10 or 11 GB, at which point the process starts to slown heavily. My question is if and how I can reduce/clean up the RAM to fetch all the required data stored in those tables.
This question already has answers here:
Retrieve column names from java.sql.ResultSet
(14 answers)
Closed 3 years ago.
I have a 3 tables I have joined this query executes and prints out the tables data.
try {
Connection conn = DriverManager.getConnection(DB_URL, USERNAME, PASSWORD);
System.out.println("Connected");
Statement st = conn.createStatement();
String query = "SELECT s.*, sup.name as supplierName , p.name as partName "+
"FROM supplies s "+
"INNER JOIN supplier sup on s.supplierNum = sup.supplierNum "+
"INNER JOIN parts p on s.partNum = p.partNum";
ResultSet rs = st.executeQuery(query);
while(rs.next()) {
System.out.println(rs.getString("supplierNum"));
System.out.println(rs.getString("partNum"));
System.out.println(rs.getString("quantity"));
System.out.println(rs.getString("supplierName"));
System.out.println(rs.getString("partName"));
space();
}
} catch(Exception ex) {
System.out.println(ex);
}
But I was trying to add the column names so instead of the console printing:
It would to print the column names cascaded
supplierNum: S1
partNum: P1
quantity: 300
name: Smith
part: Nut
As suggested in https://stackoverflow.com/a/696794/11226302
You need to get the ResultSet meta data to programmatically get your column names from db.
Else, you can manually enter the names as suggested in other answers.
while(rs.next()) {
System.out.println("Supplier Name " + rs.getString("supplierNum"));
System.out.println("Part Name "+rs.getString("partNum"));
System.out.println("Quantity "+ rs.getString("quantity"));
System.out.println("SupplierName "+rs.getString("supplierName"));
System.out.println("PartName "+rs.getString("partName"));
space();
}
You can of course hard-code the column names because you already know them.
If you want to get them programmatically, then use the ResultSetMetaData similar to this:
Connection connection = ...
try (PreparedStatement ps = connection.prepareStatement(QUERY)) {
ResultSet resultSet = ps.executeQuery();
// get the meta data from the result set
ResultSetMetaData rsMeta = resultSet.getMetaData();
// receive the column count
int columnCount = rsMeta.getColumnCount();
// iterate them (their indexes start at 1, I think)
for (int i = 1; i < columnCount + 1; i++) {
// and print the column name, the type and the type name
System.out.println(rsMeta.getColumnName(i)
+ " ("
+ rsMeta.getColumnType(i)
+ ", "
+ rsMeta.getColumnTypeName(i)
+ ")");
}
} catch ...
...
}
If you want to directly output the column in your while loop, then get the meta data before that loop
ResultSetMetaData rsMeta = rs.getMetaData();
and then, inside the loop do
System.out.println(rsMeta.getColumnName(1) + ": " + rs.getString("supplierNum"));
System.out.println(rsMeta.getColumnName(2) + ": " + rs.getString("partNum"));
System.out.println(rsMeta.getColumnName(3) + ": " + rs.getString("quantity"));
System.out.println(rsMeta.getColumnName(4) + ": " + rs.getString("supplierName"));
System.out.println(rsMeta.getColumnName(5) + ": " + rs.getString("partName"));
From a resultSet you can optain his metadata
ResultSetMetaData meta = rs.getMetaData();
int cols = meta.getColumnCount();
for (int i = 1; i <= cols; i++) {
String colName = meta.getColumnName(i);
System.out.printf("%s=%s\n", colName, rs.getString(i);
...
}
I am trying to get matricule of every item on the JList and the stage_ID from a JTextField and insert them in the table employé_stage that contains only two columns stage_ID and matricule as foreign keys respectively referencing the tables stage and employés. I want all the records from JList to be inserted in the table employé_stage with the same stage_ID I'm using this code that returns can not add or update child row: foreign constraint fails
private void addstageActionPerformed(java.awt.event.ActionEvent evt){
try{
for (int i = 0; i < stagelist.getModel().getSize(); i++) {
String item = stagelist.getModel().getElementAt(i).toString();
String[] items =item.split(" ");
if(items.length >= 2){
String sql ="INSERT INTO stage (nature,datedebs,datefs,durée_S,commentaire,stage_ID) values(?,?,?,?,?,?) ";
String sql2="INSERT INTO employé_stage (matricule) Select matricule from employés where nom='"+items[0]+"' and prénom='"+items[1]+"' ";
String sql3="INSERT INTO employé_stage (stage_ID) select LAST(stage_ID)from stage ";
ps2 = conn.prepareStatement(sql2);
ps3 = conn.prepareStatement(sql3);
ps = conn.prepareStatement(sql);
ps.setString(6,stageID.getText());
ps.execute();
ps2.execute();
ps3.execute();
}
}
} catch(Exception ev){
JOptionPane.showMessageDialog(null, ev);
}
miseajour_tab();
}
You are getting the foreign key exception because sql2 and sql3 are inserting one record each, and the foreign key constraints require that both fields be populated in each record.
You must merge these two into one insert statement like:
String sqlboth="INSERT INTO employé_stage (stage_id, matricule) " +
"( " +
" select LAST(s.stage_ID), e.matricule from stage s, employés e " +
" where e.nom='"+items[0]+"' and e.prénom='"+items[1]+"'" +
")";
Further, you should use placeholders in the insert so you are not vulnerable to SQL injection attacks.
String sqlboth="INSERT INTO employé_stage (stage_id, matricule) " +
"( " +
" select LAST(s.stage_ID), e.matricule from stage s, employés e " +
" where e.nom=? and e.prénom=?" +
")";
PreparedStatement psboth = conn.prepareStatement(sqlboth);
psboth.setString(1, items[0]);
psboth.setString(2, items[1]);
psboth.executeUpdate();
i tried with this piece of code, it works but it only inserts the first record of th JList :
private void addstageActionPerformed(java.awt.event.ActionEvent evt) {
try{
for (int i = 0; i < stagelist.getModel().getSize(); i++) {
String item = stagelist.getModel().getElementAt(i).toString();
String[] items =item.split(" ");
if(items.length >= 2){
String sql2="INSERT INTO employé_stage (stage_id, matricule) " +
"VALUES ( " +
" ?, " +
" (Select matricule from employés where nom='"+items[0]+"' and prénom='"+items[1]+"')" +
")";
ps2 = conn.prepareStatement(sql2);
ps = conn.prepareStatement(sql);
ps2.setString(1,stageID.getText());
ps.execute();
ps2.execute();
}}
} catch(Exception ev){
JOptionPane.showMessageDialog(null, ev);
}
miseajour_tab();
}
public synchronized void saveMatchValue(int photoRecOwner,
int[] photoRecAssign, float[] value) {
SQLiteDatabase database = databaseHelper.getWritableDatabase();
database.beginTransaction();
String sql = " UPDATE " + TypeContract.CTablePhotoMatch.TABLE_NAME
+ " SET " + TypeContract.CTablePhotoMatch.VALUE + "=? "
+ " WHERE " + TypeContract.CTablePhotoMatch.FK_OWNER
+ "=? AND " + TypeContract.CTablePhotoMatch.FK_ASSIGN + "=? ;"
+ " INSERT OR IGNORE INTO "
+ TypeContract.CTablePhotoMatch.TABLE_NAME + "("
+ TypeContract.CTablePhotoMatch.FK_OWNER + ","
+ TypeContract.CTablePhotoMatch.FK_ASSIGN + ","
+ TypeContract.CTablePhotoMatch.VALUE + ") VALUES (?, ?, ?);";
SQLiteStatement stmt = database.compileStatement(sql);
try {
int rows = photoRecAssign.length;
for (int i = 0; i < rows; i++) {
if (photoRecOwner > photoRecAssign[i]) {
stmt.bindLong(1, photoRecOwner);
// stmt.bindLong(index, value)
stmt.bindLong(2, photoRecAssign[i]);
} else {
stmt.bindLong(1, photoRecAssign[i]);
stmt.bindLong(2, photoRecOwner);
}
stmt.bindDouble(3, value[i]);
stmt.execute();
stmt.clearBindings();
}
database.setTransactionSuccessful();
} finally {
stmt.close();
// updtStmt.close();
database.endTransaction();
// database.close();
}
}
Without error and compile-error,
I dont know if the sql statement syntax is correct: concrete the : ; , but without compile errors, the insert and(probably update) command are not executed....
Can I catch some more details?(Of sqlite statemenst) to find out the bug
You can only use SQLiteStatement to execute single statements. The SQL after the ; is not executed.
Split the SQL to execute the statements separately.
This question already has answers here:
ResultSet exception - before start of result set
(6 answers)
Closed 9 years ago.
I'm trying to create a query within a results set loop but I keep getting the error "Before start of result set". I've attempted many different methods but they keep coming up with the same error.
Can someone help me out here?
String insertSQL = "INSERT INTO MonthlyReportTable VALUES(NULL,"; //Primary Key.
String PlannetSchemeCode = "";
int ResponcibleAuthorityID = 0;
Statement stmt = ConnectionDetails.getNewConnectionPPARSDB().createStatement();
ResultSet resultsSet = stmt.executeQuery("SELECT * FROM planning_scheme");
Statement insideStatement = ConnectionDetails.getNewConnectionPPARSDB().createStatement();
//Loop though each planning scheme and create the data for each field.
while (resultsSet.next())
{
PlannetSchemeCode = "'" + resultsSet.getString("ps_code") + "'";
//Planning Scheme Primary Key
insertSQL += PlannetSchemeCode + ",";
/*
//Responsible Authority ID
insertSQL += "'" + String.valueOf(
ResponcibleAuthorityID = MySQLUtil.getResults(
ConnectionDetails.Database_Connection_PPARSDB,
"SELECT resp_authority_id " +
"FROM resp_authority_to_ps " +
"WHERE ps_code = " + PlannetSchemeCode
)
.getInt("resp_authority_id")
) + "'";
*/
ResultSet insideResultsSet =
insideStatement.executeQuery(
"SELECT resp_authority_id " +
"FROM resp_authority_to_ps " +
"WHERE ps_code = " + PlannetSchemeCode
);
//ERROR HERE, some reason results set is getting set wrong??
//Error here, this current results set is resetting the Results set.
ResponcibleAuthorityID = insideResultsSet.getInt("resp_authority_id");
//Total_Received_CM
//Add the rest of the values temporary.
int FeildsAdded = 3;
for(int i = 1 + FeildsAdded; i < 458; i++)
{
insertSQL += String.valueOf(0) + ",";
}
//Insert date and end SQL string.
insertSQL += "NOW()";
insertSQL += ")";
System.out.println(insertSQL);
//Do Insert in PPARS.
//stmt.executeQuery(insertSQL);
//Reset the SQL String for the new Row.
insertSQL = "INSERT INTO MonthlyReportTable VALUES(NULL,";
}
A ResultSet cursor is initially positioned before the first row; the first call to the method next makes the first row the current row; the second call makes the second row the current row, and so on.
You need to call ResultSet#next() before you can read the returned data.
ResultSet insideResultsSet = insideStatement.executeQuery(
"SELECT resp_authority_id " +
"FROM resp_authority_to_ps " +
"WHERE ps_code = " + PlannetSchemeCode
);
if (insideResultsSet.next()) {
ResponcibleAuthorityID = insideResultsSet.getInt("resp_authority_id");
// etc...
}