error after inserting few rows in database using java program - java

I am trying to insert values from one server to another using java program. Here is my code:-
public static void main(String[] args) throws FileNotFoundException {
// TODO code application logic here
try {
Class.forName("oracle.jdbc.OracleDriver");
} catch (Exception exception) {
}
Connection conn = null;
Connection conn1 = null;
ResultSet rs, rs1 = null;
Statement pst = null;
try {
// dbConnect.executequery(sdate, edate);
conn = DriverManager.getConnection("jdbc:oracle:thin:#31.4.224.76:1521:RPTPSG", "pihist", "pihist");
String query = "select * from messagemasterhistory where ROWNUM<=1572660";
// String query="select * from messagemasterhistory where createdate>='28-JAN-11' and createdate<='18-FEB-2011'";
pst = conn.createStatement(java.sql.ResultSet.TYPE_FORWARD_ONLY, java.sql.ResultSet.CONCUR_READ_ONLY);
// String sql="insert into test(SRN ,UTR) values (";
// pst=conn.prepareStatement(sql);
// rs.absolute(2000);
// pst.setFetchSize(2000);
// pst.setMaxRows(1500000);
pst.setFetchDirection(ResultSet.FETCH_FORWARD);
rs = pst.executeQuery(query);
// String statment="insert into test(UTR,SRN) values('abc','1')";
// PrintWriter wt=new PrintWriter("ritima2.txt");
conn1 = DriverManager.getConnection("jdbc:oracle:thin:#31.4.224.81:1521:RPTPSG", "rptr", "rptr");
Statement stat1 = conn1.createStatement();
while (rs.next()) {
String str = rs.getString("FIELDDATA");
String str1 = rs.getString("FIELDINFO");
String statment = "insert into MESSAGEMASTERHISTORY2(UTR,CREATEDATE,SENDER,RECEIVER,SUBMESSAGETYPE,FIELDINFO,FIELDDATA,DUPLICATE) values(" + "'" + rs.getString("UTR") + "'" + "," + "TO_DATE('" + rs.getDate("CREATEDATE") + "'" + ",'YYYY-MM-DD\" \"HH24:MI:SS')" + "," + "'" + rs.getString("SENDER") + "'" + "," + "'" + rs.getString("RECEIVER") + "'" + "," + "'" + rs.getString("SUBMESSAGETYPE") + "'" + "," + "'" + str1 + "'" + "," + "'" + str + "'" + "," + rs.getInt("DUPLICATE") + ")";
// String statment="insert into test1 (fielddata,utr) values("+"'"+(rs.getString("fielddata"))+"'"+","+"'"+rs.getString("UTR")+"')";
System.out.println(count);
stat1.executeQuery(statment);
System.out.println(str);
System.out.println(str1);
// System.out.println(rs.getClob("FIELDDATA"));
System.gc();
count++;
}
conn1.commit();
conn1.close();
// wt.close();
System.out.println("Completed");
conn.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
After inserting few rows (6274) it gives error"java.sql.SQLException: ORA-00917: missing comma
at oracle.jdbc.driver.DatabaseError.throwSqlException(DatabaseError.java:113)
at oracle.jdbc.driver.T4CTTIoer.processError(T4CTTIoer.java:331)
at oracle.jdbc.driver.T4CTTIoer.processError(T4CTTIoer.java:288)
at oracle.jdbc.driver.T4C8Oall.receive(T4C8Oall.java:754)
at oracle.jdbc.driver.T4CStatement.doOall8(T4CStatement.java:210)
at oracle.jdbc.driver.T4CStatement.executeForRows(T4CStatement.java:963)
at oracle.jdbc.driver.OracleStatement.doExecuteWithTimeout(OracleStatement.java:1192)
at oracle.jdbc.driver.OracleStatement.executeQuery(OracleStatement.java:1315)
at javaapplication2.Main.main(Main.java:73)

One of the Strings you are copying from the source database probably has an illegal SQL code sequence in it.
You should consider using a PreparedStatement with parameters instead of constructing the SQL using String concatenation. The PreparedStatement should be pre-compiled, and you don't need to worry about escaping your Strings.
Something like:
String statment = "insert into MESSAGEMASTERHISTORY2(UTR,CREATEDATE,SENDER,RECEIVER,SUBMESSAGETYPE,FIELDINFO,FIELDDATA,DUPLICATE) values(?,?,?,?,?,?,?,?)";
PreparedStatement ps = conn1.prepareStstement(statement)
while (rs.next()) {
ps.setString(1, rs.getString("UTR"));
ps.setDate(2, rs.getDate("CREATEDATE"));
// etc etc
ps.executeUpdate();
conn1.commit(); //maybe you want this outside the loop
}
See http://docs.oracle.com/javase/tutorial/jdbc/basics/prepared.html

That's not a very safe way to insert data in a database.
It's vulnerable to SQL injection. Which is probably what's happening.
You probably have a ' in your inserted data somewhere, which ends the query too soon.
You should check this article out, it'll show you how to use prepared statements, or other ways to protect your query.
https://www.owasp.org/index.php/SQL_Injection_Prevention_Cheat_Sheet
If you're curious you could also look into Hibernate. With a bit of configuration, it can safely persist your entities without having to write lengthy queries yourself
http://docs.jboss.org/hibernate/orm/4.2/quickstart/en-US/html/

Related

ORA-00923: FROM keyword not found where expected in SeleniumWebDriver

I created a class (ValidarStatusOsPage) in java that makes a connection to the DB and returns to a test class (ValidateStatusOsTest) the result of the query and prints to the screen.
When I run the test class, the Eclipse console displays the message:
ORA-00923: FROM keyword not found where expecte
I have reviewed the code several times but I can not verify where the error is.
Below is the Java class for connecting to the DB and the test class.
public class ValidarStatusOsTest {
static String query;
#Test
public void validarOs() {
ValidarStatusOsPage os = new ValidarStatusOsPage();
query = os.returnDb("179195454");
}}
public class ValidarStatusOsPage {
String resultado;
public String returnDb(String NuOs) {
// Connection URL Syntax: "jdbc:mysql://ipaddress:portnumber/db_name"
String dbUrl = "jdbc:oracle:thin:#10.5.12.116:1521:desenv01";
// Database Username
String username = "bkofficeadm";
// Database Password
String password = "bkofficeadmdesenv01";
// Query to Execute
String query = "SELECT NU_OS, CD_ESTRATEGIA, CD_STATUS, NU_MATR, DT_ABERTURA" +
"FROM tb_bkoffice_os"+
"WHERE NU_OS ="+ NuOs +"";
try {
// Load mysql jdbc driver
Class.forName("oracle.jdbc.driver.OracleDriver");
// Create Connection to DB
Connection con = DriverManager.getConnection(dbUrl, username, password);
// Create Statement Object
Statement stmt = con.createStatement();
// Execute the SQL Query. Store results in ResultSet
ResultSet rs = stmt.executeQuery(query);
// While Loop to iterate through all data and print results
while (rs.next()) {
String NU_OS = rs.getString(1);
String CD_ESTRATEGIA = rs.getString(2);
String CD_STATUS = rs.getString(3);
String NU_MATR = rs.getString(4);
String DT_ABERTURA = rs.getString(5);
resultado = NU_OS + " " + CD_ESTRATEGIA + " " + CD_STATUS + " " + NU_MATR + " " + DT_ABERTURA + "\n";
System.out.println(NU_OS + " - " + CD_ESTRATEGIA + " - " + CD_STATUS + " - " + NU_MATR + " - "+ DT_ABERTURA);
}
// closing DB Connection
con.close();
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (SQLException e) {
e.printStackTrace();
}
return resultado;
}}
3 points are there in your query:
SELECT NU_OS, CD_ESTRATEGIA, CD_STATUS, NU_MATR, DT_ABERTURA" +
"FROM tb_bkoffice_os"+
"WHERE NU_OS ="+ NuOs +""
space before FROM missed first part of query is: SELECT NU_OS, CD_ESTRATEGIA, CD_STATUS, NU_MATR, DT_ABERTURAFROM
space missed before WHERE: SELECT NU_OS, CD_ESTRATEGIA, CD_STATUS, NU_MATR, DT_ABERTURAFROM tb_bkoffice_osWHERE NU_OS =
concatenate parameter into SQL string is exact hack point for SQL Injection attack. Never do it in real program even if it is pure standalone. Always use parameters for queries.
and a little last one: + NuOs +"" - last "" has no sense at all...
good luck.
UPD: #YCF_L absolutely right use Prepared statement.
you need to do this:
in Sql String: WHERE NU_OS = ?
in code:
PreparedStatement stmt = con.prepareStatement(query);
stmt.setString(1, NuOs);
//also works: stmt.setObject(1,NuOs);
things to remember with JDBC:
all parameters in SQL are just ? marks
parameter indexes start with 1 (not 0)
and in order they appear in SQL from strat to end
(e.g. Select * FROM tbl WHERE col1=? and col2=?
has parameter 1 for col1 and parameter 2 for col2
PS. your initial SQL has one more error but I'm not going to tell you what is it :-) use parameter and all be fine.

Code exiting try and going in catch after first executeQuery?

I am a beginner in android development. This is a part of my sign up code in my first android studio app: The code is going into catch right after the first execute query line and not executing my second query. If i check the Database a user is added but not a fan.
Any idea why? Any help is appreciated.
try {
Connection con = connectionClass.CONN();
if (con == null) {
z = "Error in connection with SQL server";
} else {
Statement stmt = con.createStatement();
String query1 = "INSERT INTO Usertb Values ('" + userid + "', '" + Password + "', '" + 1 + "')";
stmt.executeQuery(query1);
String query = "INSERT INTO Fan Values ('" + FirstName + "', '" + LastName + "','" + Age + "', '" + Email + "', '"
+ null + "', '" + i + "', '" + null + "')";
rs = stmt.executeQuery(query);
if (rs.next()) {
z = "Sign Up successfull";
isSuccess = true;
}
}
} catch (Exception ex) {
isSuccess = false;
z = "Exceptions";
}
One has to use executeUpdate (INSERT/UPDATE) instead of executeQuery.
String sql = "INSERT INTO Usertb(userid, passw, n) VALUES (?, PASSWORD(?), ?)";
try (PreparedStatement stmt = con.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS)) {
stmt.setString(1, userName);
stmt.setString(2, password);
stmt.setInt(3, 1);
int updateCount = stmt.executeUpdate(query1); // 1 when 1 record inserted
if (updateCount != 0) {
// If you want to use an autincrement primary key:
try (ResultSet rsKeys = stm.getGeneratedKeys()) {
if (rsKeys.next()) {
long id = rsKeys.getLong(1);
}
}
}
} // Closes stmt
Furthermore it is very important to use prepared statements to prevent SQL injection. It also takes care of single quotes and backslash in the strings.
Additionally there is shown how to use AUTOINCR fields, to retrieve a database generated key, for example for the second INSERT.
For the second use a new PreparedStatement.
Passwords should better be stored encrypted in the database, should someone steal the data. You might look into that subject. My solution is quite minimal, look for seeding and other encryption functions.

ORA-00917: missing comma - Insert query failed

I'm trying to create insert query in JSP page as follows
try
{
Class.forName("oracle.jdbc.driver.OracleDriver");
}
catch (ClassNotFoundException e)
{
e.printStackTrace();
}
try
{
connection = DriverManager.getConnection(
"jdbc:oracle:thin:#localhost:1521:" + "XE", "hr","hr");
if (connection != null)
{
statement = connection.createStatement();
String q2 = "INSERT INTO HR.tweets (";
q2 = q2 + "DATE_TIME,USER_NAME,TWEET_BEFORE,TWEET_AFTER)";
q2 = q2 + "VALUES (";
q2 = q2 + "(select SYSDATE from dual),";
q2 = q2 + "'" + tweet.getUser().getScreenName() + "'" + ",";
q2 = q2 + "'" + tweet.getText() + "'" +",";
q2 = q2 + "'" + finalstring + "')";
statement.execute(q2);
statement.close();
connection.close();
}
}
catch (SQLException e)
{
e.printStackTrace();
}
At statement.execute(q2) I'm getting ORA-00917: missing comma error.
The following query is created in a code :
INSERT INTO HR.tweets (DATE_TIME,USER_NAME,TWEET_BEFORE,TWEET_AFTER)VALUES ((select SYSDATE from dual),'Dannazxcv','RT #HugotInhinyero: Wish we could turn back time to the good old days. When our mama sings us to sleep but now we're stressed out.🎶🎶
#engin…','hugotinhinyero turn back time good days. mama sing sleep we're stress out. engin' )
Please help me.
Your SQL insert has an syntax error since one of your parameters contains a ':
'hugotinhinyero turn back time good days. mama sing sleep we're stress out. engin'
To avoid this kind of errors, don't build SQL strings manually, but use a PreparedStatement and parameters instead:
String insert = "INSERT INTO HR.tweets (DATE_TIME,USER_NAME,TWEET_BEFORE,TWEET_AFTER) " +
" VALUES ((select SYSDATE from dual),?,?,?)";
PreparedStatement stmt = connection.prepareStatement(insert);
stmt.setParameter(1, tweet.getUser().getScreenName());
stmt.setParameter(2, tweet.getText());
stmt.setParameter(3, finalstring);
stmt.executUpdate();
Use PreparedStatement instead of Statement.
Your query will always fail if any of your field will contain quote character (').
Besides, your query is vulnerable to SQL injection attack, while PreparedStatement guards against a such attack.
Details on PreparedStatement can be found in this tutorial:
http://docs.oracle.com/javase/tutorial/jdbc/basics/prepared.html
This is a very very basic knowledge so I dont't explain it here.
The problem here is that you are using special characters, which causes the statement sent through to the database to be invalid.
Try using a prepared statement like this...
PreparedStatement pstatement = null;
Connection connection = null;
try
{
connection = DriverManager.getConnection(
"jdbc:oracle:thin:#localhost:1521:" + "XE", "hr","hr");
if (connection != null)
{
pstatement = connection.prepareStatement("INSERT INTO HR.tweets (DATE_TIME,USER_NAME,TWEET_BEFORE,TWEET_AFTER) VALUES ((select SYSDATE from dual),?,?,?)");
q2 = q2 + "'" + tweet.getUser().getScreenName() + "'" + ",";
q2 = q2 + "'" + tweet.getText() + "'" +",";
q2 = q2 + "'" + finalstring + "')";
pstatement.setString(1, tweet.getUser().getScreenName());
pstatement.setString(2,tweet.getText());
pstatement.setString(3, finalstring);
pstatement.execute();
}
}
catch (SQLException e)
{
e.printStackTrace();
}finally{
pstatement.close();
connection.close();
}
...prepared statements usually take care of malformed strings and invalid quotes sent to the DB.
As mentioned by #wero, the issue with the query is that it contains a quote ('). To escape it you can use a backslash (\).
Eg: we\'re
However like other's have suggested, its safer to use prepared-statements which also take care of guarding against sql-injection as a bonus !

Resultset.next returns true but doesn't return the value

I am trying to read from a mysql table and I am doing the following:
protected void pushRegisteredStudentsData() {
try {
conn = (Connection) DriverManager.getConnection(DB_URL, USER, PASS);
stmt = conn.createStatement();
String userID = "SELECT * FROM STUDENT";
rs = stmt.executeQuery(userID);
while (rs.next()) {
int id = rs.getInt("ID");
this.studentID = id;
String insertSql = "INSERT INTO REGISTEREDSTUDENTS(StudentID, ModuleCode) VALUES ('" + studentID + "', + '"
+ this.moduleCode + "')";
System.out.println("Inserting into REGISTEREDSTUDENTS.. [" + id + "]" + "[" + this.moduleCode + "]");
stmt.executeUpdate(insertSql);
}
} catch (SQLException e) {
}
}
..but for some reason,
while (rs.next()) {
int id = rs.getInt("ID");
always returns the same ID, even though the table has different ID's on every line!
Does anyone have an idea why that might be?
Thank you in advance! :(
EDIT:
I was using a single statement to execute 2 updates, which was causing the problem!
It is a bit weird that it returns always the same value because it should only return the first value ONCE.
If you print the stacktrace instead of just catching the exception and doing nothing, you will see that it will print something like:
java.sql.SQLException: Operation not allowed after ResultSet closed
at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:1073)
at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:987)
at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:982)
at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:927)
at com.mysql.jdbc.ResultSetImpl.checkClosed(ResultSetImpl.java:794)
You are using THE SAME statement for a Select and then for an Insert. This causes the resultSet that is "attached" to the Statement to close because it is not supposed to be used again.
It can be easily fixed by creating another statement:
String insertSql = "INSERT INTO REGISTEREDSTUDENTS(StudentID, ModuleCode) VALUES ('" + studentID + "', + '"
+ this.moduleCode + "')";
System.out.println("Inserting into REGISTEREDSTUDENTS.. [" + id + "]" + "[" + this.moduleCode + "]");
Statement stmt2 = conn.createStatement();
stmt2.executeUpdate(insertSql);

SQL - Making tables

Below is my code. I'm trying to get the two results on a same table but somehow I can only get them on separate table. Is there a way somehow to get both the tables to be linked together.
For example:
Result1:
Active Day
Year\\\Day\\\ Total
2014\\\1\\\\\\\ MY
and
Result2:
Timing
Year\\\Month\\\ Total
2014\\\12\\\\\\\\\ SG
to
Active Day\\\\\\\\\\\\\\\\\\\\ Timing
Year\\\Day\\\ Total\\\\\\\\\\Month\\\ Total
2014\\\1\\\\\\\ MY\\\\\\\\\\\\\12\\\\\\\\\ SG
public static String Summary() {
String strResult="", result1="", result2=""
Connection conn = null;
try {
Class.forName("com.mysql.jdbc.Driver");
conn = DriverManager.getConnection(DB_URL, USER, PASS);
String sql;
Class.forName("com.microsoft.sqlserver.jdbc.SQLServerDriver");
Connection connection = DriverManager.getConnection(url);
Statement statement = connection.createStatement();
sql = "EXECUTE GEOIP.dbo.CF_VIEW_DAILY_STAT'"+yesterdayDate()+"';";
CallableStatement cstmt = connection.prepareCall(sql);
boolean hasMoreResultSets = cstmt.execute();
if (!hasMoreResultSets) {
//System.out.println("The first result is not a ResultSet.");
return strResult;
}
//First Result
ResultSet rs = cstmt.getResultSet();
result1 = "<table cellpadding='2' cellspacing='0' border='1'><tbody>"
+ "<tr class='title1'><td colspan='4'>Active Day</td></tr>"
+ "<tr class='title2'><td class='v_date' style='text-align:left'>Date</td><td class='v_number'>Day (s)</td><td class='v_number'>Country / Total</td><td class='v_number'>Active Count</td>"
+ "</tr>";
while (rs.next()) {
result1 += "<tr>"
+ "<td id='col1row1' class='v_date'>" + rs.getString("StatDt") + "</td><td class='v_number'>" + String.format("%,d", rs.getInt("ActiveDay"))
+ "</td><td class='v_number'>" + rs.getString("Country") + "</td><td class='v_number'>" + String.format("%,d", rs.getInt("ActiveCnt")) + "</td>"
+"</tr>";
}
result1 += "</tbody></table><br/><br/>";
rs.close();
//Second Result
hasMoreResultSets = cstmt.getMoreResults();
if (!hasMoreResultSets) {
//System.out.println("The first result is not a ResultSet.");
return strResult;
}
ResultSet rs = cstmt.getResultSet();
result2 = "<table cellpadding='2' cellspacing='0' border='1'><tbody>"
+ "<tr class='title1'><td colspan='3'>Conversion</td></tr>"
+ "<tr class='title2'><td class='v_date'>Date</td><td class='v_number'>NRU</td>"
+ "<td class='v_number'>NRU_Play</td>"
+ "</tr>";
while (rs.next()) {
result2 += "<tr>"
+ "<td class='v_date'>"+ rs.getString("StatDt") + "</td><td class='v_number'>" + String.format("%,d", rs.getInt("NRU"))
+ "</td><td class='v_number'>" + String.format("%,d", rs.getInt("NRU_Play"))
+ "</tr>";
}
result2 += "</tbody></table><br/><br/>";
rs.close();
cstmt.close();
connection.close();
} catch (SQLException se) {
// Handle errors for JDBC
se.printStackTrace();
} catch (Exception e) {
// Handle errors for Class.forName
e.printStackTrace();
}
strResult = result1 + result2;
System.out.print(strResult);
return strResult;
}
How do I possibly get them on the same row, like linking them together [ignoring the year because it's the same]. Any help? I'm new to SQL here.
Suggestions:
Create a common java object to store data read from both result sets.
Read first result set and fill the data object.
Read next result set and fill the data object with rest of fields.
Now loop through the data object to that many number of items filled
with.
Construct the html 'tr' and 'td' to fill in each row as desired.
Change your CF_VIEW_DAILY_STAT view and get all the data in single resultset
For Example
SELECT Year1,Day1,Total1
FROM #ActiveDay
UNION
SELECT Month1,Total1
FROM #Timing
for the example i have changed the columns names because you are using reserved keyword in example.
use two different prepared or callable statements and combine the two different resultsets obtained.
String str=rs.getString(1) + " "+rs.getString(2);

Categories