why I can not insert into oracle in jdbc? - oracle

My goal is to transfer a series of songs from the songs table in SQLite DB to a songs table in oracle DB. First I select the information from SQLite and then transfer it to the oracle's songs, but it gives the following error.
try {
ResultSet resultSet = sqliteConnectionStatement.executeQuery("select * from songs");
while (resultSet.next()) {
oracleConnectionStatement.execute("insert into songs values (" + resultSet.getInt("_id") +
"," + resultSet.getInt("track") +
",'" + resultSet.getString("title") +
"'," + resultSet.getInt("album") + ")");
}
System.out.println("data transferred with no error");
resultSet.close();
} catch (SQLException e) {
System.out.println("Oops!something went wrong! : " + e.getMessage());
e.printStackTrace();
}
output:
Oops! something went wrong! : ORA-00917: missing comma
java.sql.SQLSyntaxErrorException: ORA-00917: missing comma
at oracle.jdbc.driver.T4CTTIoer11.processError(T4CTTIoer11.java:630)
at oracle.jdbc.driver.T4CTTIoer11.processError(T4CTTIoer11.java:564)
at oracle.jdbc.driver.T4C8Oall.processError(T4C8Oall.java:1231)
at oracle.jdbc.driver.T4CTTIfun.receive(T4CTTIfun.java:772)
at oracle.jdbc.driver.T4CTTIfun.doRPC(T4CTTIfun.java:299)
at oracle.jdbc.driver.T4C8Oall.doOALL(T4C8Oall.java:512)
at oracle.jdbc.driver.T4CStatement.doOall8(T4CStatement.java:123)
at oracle.jdbc.driver.T4CStatement.executeForRows(T4CStatement.java:1200)
at oracle.jdbc.driver.OracleStatement.executeSQLStatement(OracleStatement.java:1820)
at oracle.jdbc.driver.OracleStatement.doExecuteWithTimeout(OracleStatement.java:1472)
at oracle.jdbc.driver.OracleStatement.executeInternal(OracleStatement.java:2505)
at oracle.jdbc.driver.OracleStatement.execute(OracleStatement.java:2460)
at oracle.jdbc.driver.OracleStatementWrapper.execute(OracleStatementWrapper.java:328)
at org.ISOFT.Main.main(Main.java:21)
Caused by: Error : 917, Position : 37, Sql = insert into songs values (1,2,'I Can't Quit You Baby',343), OriginalSql = insert into songs values (1,2,'I Can't Quit You Baby',343), Error Msg = ORA-00917: missing comma
at oracle.jdbc.driver.T4CTTIoer11.processError(T4CTTIoer11.java:637)
... 13 more

NEVER build an SQL statement using string concatenation. Your code will be vulnerable to SQL injection attacks and if you run the same query with different parameters then the SQL engine will need to parse it every time making everything slower.
Use a prepared statement and bind variables. The code will not be vulnerable to SQL injections attacks and the SQL engine will only need to parse it once and then can reuse the previous execution plan.
Something like (untested):
ResultSet resultSet;
try {
resultSet = sqliteConnectionStatement.executeQuery(
"select * from songs"
);
oracleConnectionStatement.setAutoCommit(false);
PreparedStatement stmt = oracleConnectionStatement.prepareStatement(
"INSERT INTO songs (id, track, title, album) VALUES (?, ?, ?, ?)"
);
while (resultSet.next()) {
stmt.setInt(1, resultSet.getInt("_id"));
stmt.setInt(2, resultSet.getInt("track"));
stmt.setString(3, resultSet.getString("title"));
stmt.setInt(4, resultSet.getInt("album"));
stmt.addBatch();
}
stmt.executeBatch();
oracleConnectionStatement.commit();
System.out.println("data transferred with no error");
} catch (SQLException e) {
System.out.println("Oops!something went wrong! : " + e.getMessage());
e.printStackTrace();
} finally {
// Close the result set
if (resultSet != null)
{
try {
resultSet.close();
} catch (Exception e){}
}
// Close the connections
try {
sqliteConnectionStatement.close();
} catch (Exception e){}
try {
oracleConnectionStatement.close();
} catch (Exception e){}
}

Related

How to verify if my JDBC query output has data in it or not

I want to verify if my JDBC query output has data in it or not. If it doesn't contain any data then it should print the assertion as false.
I tried using this:
System.out.println("Table contains "+rs.getRow()+" rows");
if (!rs.next())
{
Assert.assertTrue(false);
}
else
{
Assert.assertTrue(true);
}
I tried using as below:
System.out.println("Table contains "+rs.getRow()+" rows");
if (!rs.next())
{
Assert.assertTrue(false);
}
else
{
Assert.assertTrue(true);
}
But it didn't work. So can anyone suggest how to solve this?
If you only need to know, how many rows are in a table, let the DBMS count them with:
select count(*) as noRows from table
And within your java code it will look like this snippet
boolean hasRows= false;
Statement stmt = null;
ResultSet rs = null;
try {
stmt = connection.createStatement();
rs = stmt.executeQuery("select count(*) as noRows from table");
if ( rs.next() ) {
if ( rs.getInt(1) > 0 ) {
hasRows = true;
}
}
} catch (SQLException sqlex ) {
// print or log an error message
} finally {
if ( rs != null ) {
try {
rs.close();
} catch (SQlException sqlex ) {
// print or log an error message
}
}
if ( stmt != null ) {
try {
stmt.close();
} catch (SQlException sqlex ) {
// print or log an error message
}
}
}
Assert.assertTrue(hasRows);
And it could also make sense to close your connection.
This will just return the rows within a table. If you need to know the size of a particular query, I for myself would do it similarly with the query and just replace the fields from the query with the count(*) or count(DISTINCT xyz) command. Try it first out within your sql monitor, because if the query runs to long, you might not be happy.

Insert/update to multiple DB connections in loop using JDBC PreparedStatement

I am working on a program which is supposed to do inserts/updates to a DB table using JDBC program. Inserts/updates need to happen to 2 separate DB instances. There is an input XML file which is read by program, input file has about 1800 records. For each record, I need to do updates as per record read from XML file if record already exists in DB. Do insert otherwise. I am using below program to do the work and it doesn't give consistent results when I execute the program. Looks like PreparedStatement for DB2 in if and else section is actually pointing to DB1 because after successful insert/update to DB1 for the first record, it fails to do the same for DB2 saying primary key violation but DB2 is a different connection and I don't have the record there so primary key violation for DB2 doesn't make sense! Seems that connection information is getting mixed somehow.
Below is how the program looks. I have given only relevant sections of the program. PreparedStatment2 and PreparedStatement4 are not giving expected results. Please note that I have verified connection2 and that's indeed pointing to DB2 and not DB1. Weird thing is that every time I execute the program, it starts working for the record which didn't work in last execution so each program execution gets me past the issue of 1 record in loop and start giving the problem for next one! Can someone help me understanding why PreparedStatement2 and 4 are not working as expected for DB2?
Thanks,
Chanchal
Connection connection1 = null;
Connection connection2 = null;
Statement statement = null;
PreparedStatement preparedStatement1 = null;
PreparedStatement preparedStatement2 = null;
PreparedStatement preparedStatement3 = null;
PreparedStatement preparedStatement4 = null;
ResultSet resultSet1 = null;
try
{
connection1 = DriverManager.getConnection(properties.getProperty(RT_DB1_URL), properties.getProperty(RT_DB1_USER), properties.getProperty(RT_DB1_PWD));
connection2 = DriverManager.getConnection(properties.getProperty(RT_DB2_URL), properties.getProperty(RT_DB2_USER), properties.getProperty(RT_DB2_PWD));
//Get list
for (int temp = 0; temp < list.getLength(); temp++) {
//Get fieldValueA,fieldValueB, fieldValueC, fieldValueD values from a XML file
//Find if record exists in DB
String selectQuery = "select * from table_x where fieldA='" + fieldValueA + "'";
resultSet1 = statement.executeQuery(selectQuery);
if(resultSet1.next()){
// Update table
String query = "update table_x set fieldB = ?,fieldC = ?,fieldD = ? where fieldA = ?";
preparedStatement1 = connection1.prepareStatement(query);
preparedStatement2 = connection2.prepareStatement(query);
preparedStatement1.setString(1, fieldValueB);
preparedStatement1.setString(2, fieldValueC);
preparedStatement1.setString(3, fieldValueD);
preparedStatement1.setString(4, fieldValueA);
int k = preparedStatement1.executeUpdate();
logger.info("Records successfully updated in RT DB1 for fieldA=" + fieldValueA);
//Closing the statement as it exceeds oracle cursor limit otherwise with default cursor limit of 300
if (preparedStatement1 != null) preparedStatement1.close();
preparedStatement2.setString(1, fieldValueB);
preparedStatement2.setString(2, fieldValueC);
preparedStatement2.setString(3, fieldValueD);
preparedStatement2.setString(4, fieldValueA);
int k = preparedStatement2.executeUpdate();
logger.info("Records successfully updated in RT DB2 for fieldA=" + fieldValueA);
//Closing the statement as it exceeds oracle cursor limit otherwise with default cursor limit of 300
if (preparedStatement2 != null) preparedStatement2.close();
}
else{
//Insert to the table
String queryInsert = "insert into table_x(fieldA,fieldB,fieldC,fieldD)";
queryInsert = queryInsert + " values(?,?,?,?)";
preparedStatement3 = connection1.prepareStatement(queryInsert);
preparedStatement4 = connection2.prepareStatement(queryInsert);
preparedStatement3.setString(1, fieldValueA);
preparedStatement3.setString(2, fieldValueB);
preparedStatement3.setString(3, fieldValueC);
preparedStatement3.setString(4, fieldValueD);
int k = preparedStatement3.executeUpdate();
logger.info("Records successfully inserted in RT DB1 for fieldA=" + fieldValueA);
if (preparedStatement3 != null) preparedStatement3.close();
preparedStatement4.setString(1, fieldValueA);
preparedStatement4.setString(2, fieldValueB);
preparedStatement4.setString(3, fieldValueC);
preparedStatement4.setString(4, fieldValueD);
int k = preparedStatement4.executeUpdate();
logger.info("Records successfully inserted in RT DB2 for fieldA=" + fieldValueA);
if (preparedStatement4 != null) preparedStatement4.close();
} // End loop
} catch (Exception e) {
e.printStackTrace();
}
finally{
try { if (resultSet1 != null) resultSet1.close(); } catch (Exception e) {e.printStackTrace();};
try { if (statement != null) statement.close(); } catch (Exception e) {e.printStackTrace();};
try { if (connection1 != null) connection1.close(); } catch (Exception e) {e.printStackTrace();};
try { if (connection2 != null) connection2.close(); } catch (Exception e) {e.printStackTrace();};
}
It is fine, to create the prepared statements before the loop. So they can be reused within every loop. Also you can do batch processing and send all data to the DBs after running all. If there are some 1000 records, it might sense to flush the batch earlier, but 1800 records can be processed within a batch in one time. I could not test this code, but I hope it gives you some hints.
Connection connection1 = null;
Connection connection2 = null;
Statement statement = null;
PreparedStatement preparedStatement1 = null;
PreparedStatement preparedStatement2 = null;
PreparedStatement preparedStatement3 = null;
PreparedStatement preparedStatement4 = null;
ResultSet resultSet1 = null;
try
{
connection1 = DriverManager.getConnection(properties.getProperty(RT_DB1_URL), properties.getProperty(RT_DB1_USER), properties.getProperty(RT_DB1_PWD));
connection2 = DriverManager.getConnection(properties.getProperty(RT_DB2_URL), properties.getProperty(RT_DB2_USER), properties.getProperty(RT_DB2_PWD));
// Update table
String query = "update table_x set fieldB = ?,fieldC = ?,fieldD = ? where fieldA = ?";
preparedStatement1 = connection1.prepareStatement(query);
preparedStatement2 = connection2.prepareStatement(query);
String queryInsert = "insert into table_x(fieldA,fieldB,fieldC,fieldD)";
queryInsert = queryInsert + " values(?,?,?,?)";
preparedStatement3 = connection1.prepareStatement(queryInsert);
preparedStatement4 = connection2.prepareStatement(queryInsert);
//Get list
for (int temp = 0; temp < list.getLength(); temp++) {
//Get fieldValueA,fieldValueB, fieldValueC, fieldValueD values from a XML file
//Find if record exists in DB
String selectQuery = "select * from table_x where fieldA='" + fieldValueA + "'";
resultSet1 = statement.executeQuery(selectQuery);
if(resultSet1.next()){
preparedStatement1.setString(1, fieldValueB);
preparedStatement1.setString(2, fieldValueC);
preparedStatement1.setString(3, fieldValueD);
preparedStatement1.setString(4, fieldValueA);
preparedStatement1.addBatch();
logger.info("Records successfully added RT DB1 for fieldA=" + fieldValueA);
preparedStatement2.setString(1, fieldValueB);
preparedStatement2.setString(2, fieldValueC);
preparedStatement2.setString(3, fieldValueD);
preparedStatement2.setString(4, fieldValueA);
preparedStatement2.addBatch();
logger.info("Records successfully added in RT DB2 for fieldA=" + fieldValueA);
}
else{
//Insert to the table
preparedStatement3.setString(1, fieldValueA);
preparedStatement3.setString(2, fieldValueB);
preparedStatement3.setString(3, fieldValueC);
preparedStatement3.setString(4, fieldValueD);
preparedStatement3.addBatch();
logger.info("Records successfully added RT DB1 for fieldA=" + fieldValueA);
if (preparedStatement3 != null) preparedStatement3.close();
preparedStatement4.setString(1, fieldValueA);
preparedStatement4.setString(2, fieldValueB);
preparedStatement4.setString(3, fieldValueC);
preparedStatement4.setString(4, fieldValueD);
preparedStatement4.addBatch();
} // End loop
// now, we are flushing the batch to the DBs
int[] k1 = preparedStatement1.executeBatch();
int[] k2 = preparedStatement2.executeBatch();
int[] k3 = preparedStatement3.executeBatch();
int[] k4 = preparedStatement4.executeBatch();
logger.info("updated " + String.format("%,d",k1.lenght) + " Records in DB1 and " + String.format("%,d",k2.lenght) + " inserted " + String.format("%,d",k3.length) + " Records in DB1 and " + String.format("%,d",k4.length) + " in DB2");
} catch (Exception e) {
e.printStackTrace();
}
finally{
try { if preparedStatement1 != null ) preparedStatement1 } catch (Exception e) {e.printStackTrace();};
try { if preparedStatement2 != null ) preparedStatement2 } catch (Exception e) {e.printStackTrace();};
try { if preparedStatement3 != null ) preparedStatement3 } catch (Exception e) {e.printStackTrace();};
try { if preparedStatement4 != null ) preparedStatement4 } catch (Exception e) {e.printStackTrace();};
try { if (resultSet1 != null) resultSet1.close(); } catch (Exception e) {e.printStackTrace();};
try { if (statement != null) statement.close(); } catch (Exception e) {e.printStackTrace();};
try { if (connection1 != null) connection1.close(); } catch (Exception e) {e.printStackTrace();};
try { if (connection2 != null) connection2.close(); } catch (Exception e) {e.printStackTrace();};
}
)

Oracle MERGE and java prepared statement

I have the below code whose sql script works perfectly on sql developer but when used in java code i.e
String MergeSQLMapping = "MERGE INTO test.test_table USING dual ON (CLN_POL_CODE = 22222) "
+ "WHEN MATCHED THEN "
+ "UPDATE SET COMPANY_NAME = 'kevin', POL_ID = '22222', MAPPED_BY = '22222' "
+ "WHEN NOT MATCHED THEN INSERT (COMPANY_NAME, POL_ID, CLN_POL_CODE, MAPPED_BY) "
+ "VALUES ('kevin', '22222', '22222', 'workerservice'); ";
System.out.println(MergeSQLMapping);
dbMergeConnection = DBConnection.getStagingConnection();
try {
PreparedStatement ps = dbMergeConnection.prepareStatement(MergeSQLMapping);
ps.execute();
dbMergeConnection.commit();
ps.close();
} catch (SQLException e) {
System.out.println(e.getMessage());
} finally {
}
i get the following error
ORA-00933: SQL command not properly ended
Any help accorded will be appreciated.

Error while trying to load data into hive table

I was able to create a table into hbase using hive now I'm trying to load data into a hive table then overwrite the data into the hbase table :
public class HiveJdbcClient {
private static String driverName = "org.apache.hadoop.hive.jdbc.HiveDriver";
/**
* #param args
* #throws SQLException
**/
public static void main(String[] args) throws SQLException {
try {
Class.forName(driverName);
} catch (ClassNotFoundException e){
// TODO Auto-generated catch block
e.printStackTrace();
System.exit(1);
}
Connection con = DriverManager.getConnection("jdbc:hive://localhost:10000/default", "", "");
Statement stmt = con.createStatement();
String tableNameHive = "hbase_trades";
String tableNameHbase= "trades";
stmt.executeQuery("drop table " + tableNameHive);
ResultSet res = stmt.executeQuery("create table " + tableNameHive + " (key string, value string) STORED BY 'org.apache.hadoop.hive.hbase.HBaseStorageHandler' WITH SERDEPROPERTIES (\"hbase.columns.mapping\" = \":key,cf1:val\") TBLPROPERTIES (\"hbase.table.name\" = \"trades\")");
String sql = "show tables '" + tableNameHive + "'";
System.out.println("Running: " + sql);
res = stmt.executeQuery(sql);
if (res.next()) {
System.out.println(res.getString(1));
}
sql = "describe " + tableNameHive;
System.out.println("Running: " + sql);
res = stmt.executeQuery(sql);
while (res.next()) {
System.out.println(res.getString(1) + "\t" + res.getString(2));
}
String filepath = "/tmp/test_hive_server.txt";
sql = "load data local inpath '" + filepath + "' into table " + tableNameHive;
System.out.println("Running: " + sql);
res = stmt.executeQuery(sql);
stmt.executeQuery("insert overwrite " + tableNameHbase+"select * from"+tableNameHive);
}
}
and I get the following error:
Running: load data local inpath '/tmp/test_hive_server.txt' into table hbase_trades
Exception in thread "main" java.sql.SQLException: Query returned non-zero code: 10101, cause: FAILED: SemanticException [Error 10101]: A non-native table cannot be used as target for LOAD
at org.apache.hadoop.hive.jdbc.HiveStatement.executeQuery(HiveStatement.java:194)
at com.palmyra.nosql.HiveJdbcClient.main(HiveJdbcClient.java:53)
could someone tell me what's the problem??

running an SQL update statement in java

There are many questions related to this topic, but I couldn't find a solution to my problem.
I have a table of "products" which I am trying to update in netbeans. The SQL statements works in SQL dev, and I have double checked my connection etc.
update products
set pvolume = 2, pprice = 15
where productid = 3;
output: 1 rows updated.
but running in netbeans it won't execute. If I have missed some small syntax issue I apologize, but I really need help with this method.
public boolean editProduct(int ID, String name, int volume, int quantity, String description, int price) {
boolean success = false;
Connection con = ConnectionTools.getInstance().getCurrentConnection();
String SQLString1 = "UPDATE products "
+ "SET pname = ?, "
+ "pvolume = ?, "
+ "pquantity = ?, "
+ "pdescription = ?, "
+ "pprice = ? "
+ "WHERE productID = ?";
PreparedStatement statement = null;
try {
statement = con.prepareStatement(SQLString1);
statement.setString(1, name);
statement.setInt(2,volume);
statement.setInt(3, quantity);
statement.setString(4, description);
statement.setInt(5, price);
statement.setInt(6, ID);
statement.executeUpdate();
success = true;
}catch (Exception e){
System.out.println("Insertion error!");
System.out.println(e.getMessage());
}finally {
try {
statement.close();
} catch (SQLException e) {
System.out.println("Statement close error!");
System.out.println(e.getMessage());
}
}
return success;
}
Running through the debug it seems to run through the try as far as statement.setInt(6, ID) but then does not execute. Here is the output:
Insertion error!
ORA-00971: missing SET keyword
Any help/advice would be appreciated! Thanks
You have to use brackets: update products set (pvolume = 2, pprice = 15) where productid = 3

Resources