I try to make a code in java that accesses some tables from sql but when I try to run the code I get an error saying:
java.sql.SQLSyntaxErrorException: ORA-00933: SQL command not properly
ended
Here is the code that it's been giving me troubles:
history.addActionListener(new ActionListener()
{
#Override
public void actionPerformed(ActionEvent actionEvent)
{
for(int i = 0; i < table.getRowCount(); i++)
for(int j = 0; j < table.getColumnCount(); j++)
table.setValueAt("", i, j);
int i=0;
try
{
rs = stmt.executeQuery("SELECT toyname, toyid, price "
+" FROM toys t, userbuy u "
+" WHERE u.toyid=t.toyid "
+" AND u.userid= "+user1.getUserid()+" )");
}
catch (SQLException e)
{
e.printStackTrace();
}
finally
{
try {
if(rs.next())
{
table.setValueAt(rs.getString(1), i, 0);
table.setValueAt(rs.getString(2), i, 1);
table.setValueAt(rs.getString(3), i, 2);
i++;
while(rs.next())
{
table.setValueAt(rs.getString(1), i, 0);
table.setValueAt(rs.getString(2), i, 1);
table.setValueAt(rs.getString(3), i, 2);
i++;
}
}
} catch (SQLException e) {
JOptionPane.showMessageDialog(null, e.getMessage());
}
}
}
});
Those are my two tables:
CREATE TABLE users
(
userid NUMBER(2) NOT NULL CONSTRAINT users_pk PRIMARY KEY,
username VARCHAR(17) NOT NULL,
password VARCHAR(20),
email VARCHAR(20),
adress VARCHAR(20),
CNP VARCHAR(14)
);
CREATE TABLE userbuy
(
userid NUMBER(2),
buyid NUMBER(2) ,
toyid NUMBER(2),
CONSTRAINT userid_fk FOREIGN KEY (userid) REFERENCES users(userid),
CONSTRAINT buyid_fk FOREIGN KEY (buyid) REFERENCES buy(buyid)
);
Does anyone know what is wrong here?
your sql query is wrong.correct sql
rs = stmt.executeQuery("SELECT toyname, toyid, price "
+" FROM toys t, userbuy u " +" WHERE u.toyid=t.toyid "
+" AND u.userid= "+user1.getUserid());
It is advisable to use PreparedStatement to get rid of sql injection
Example of PreparedStatement
correct sql query :
rs = stmt.executeQuery("SELECT t.toyname, t.toyid, t.price "
+" FROM toys t, userbuy u "+" WHERE u.toyid=t.toyid "
+" AND u.userid= "+user1.getUserid());
remove that " )", may be you forgot it :)
Related
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();};
}
)
I am making board and now trying to make search function.
but values doesn't come out if I search keyword
I have tried to run on oracle with printed sql and parameter(optionText,searchText..) it worked fine but result set doesnt have value
public List<boardVO> getBoardList(String optionText,String searchText,int totalNum , int nowPage){
List<boardVO> list = new ArrayList<boardVO>();
try {
connectDB();
String sql = "select * from "
+ "(select rownum as rnum,recordno,userid,title,content,views,regdate from";
if(optionText!=null && !optionText.equals("") && searchText!=null &&!searchText.equals("")) {
sql += " (select * from boardlist where ? like ?))";
}else{
sql += " boardlist)";
}
sql += "where rnum>=? and rnum<=? order by recordno desc";
pstmt = conn.prepareStatement(sql);
int finalNum = totalNum -(5*(nowPage-1));
if(optionText!=null && !optionText.equals("") && searchText!=null &&!searchText.equals("")) {
pstmt.setString(1, optionText);
pstmt.setString(2, "%"+searchText+"%");
if(finalNum>4) {
pstmt.setInt(3, finalNum-4);
pstmt.setInt(4, finalNum);
}else {
pstmt.setInt(3, 1);
pstmt.setInt(4, finalNum);
}
}else {
pstmt.setInt(1, finalNum-4);
pstmt.setInt(2, finalNum);
}
rs = pstmt.executeQuery();
while(rs.next()) {
boardVO vo = new boardVO();
System.out.println("while");
vo.setRecordNo(rs.getInt(2));
vo.setUserid(rs.getString(3));
vo.setTitle(rs.getString(4));
vo.setContent(rs.getString(5));
/* System.out.println(vo.getContent()); */
vo.setViews(rs.getInt(6));
vo.setRegdate(rs.getString(7));
list.add(vo);
}
} catch (Exception e) {
System.out.println("get board list error");
e.printStackTrace();
}finally {
closeDB();
}
return list;
}
I think this is your problem:
(select * from boardlist where ? like ?)
It looks like you are trying to pass both a column name and a searchable value to your query: you can't do this with parameters. Both assignments will be treated as literals, so your executed code will be something like this:
select * from boardlist where 'COLUMN_NAME` like '%some string%'
Perfectly valid SQL, just won't return any results.
If this is the case you need to change the assemblage of the statement to include the column name ...
if(optionText!=null && !optionText.equals("") && searchText!=null &&!searchText.equals("")) {
sql += " (select * from boardlist where " + optionText + " like ?))";
}else{
... and remove the parameter assignment:
if(optionText!=null && !optionText.equals("") && searchText!=null &&!searchText.equals("")) {
pstmt.setString(1, "%"+searchText+"%");
This was reported by HibernateTools Reverse Engineering, but it seems to be true.
oracle jdbc driver reports no primary key columns on a table that has a primary key.
#Test
public void checkTable() throws SQLException, IOException {
System.out.println("in check table");
assertNotNull(conn);
Statement s = conn.createStatement();
ResultSet rset = s.executeQuery("select user from dual");
rset.next();
String username = rset.getString(1);
rset.close();
try {
s.execute("drop table " + username + ".x");
} catch (Exception e) {
// nothing it might not exist
}
s.execute("create table " + username + ".x (y number)");
s.execute("alter table x add constraint x_pk primary key (y)");
DatabaseMetaData meta = conn.getMetaData();
final String[] tableTypes = new String[] { "TABLE", "VIEW" };
ResultSet rs = meta.getTables(null, username, "X",tableTypes);
rs.next();
String table = rs.getString("table_name");
System.out.println("table is " + table);
rs.close();
rs = s.executeQuery("select * from user_constraints where table_name = 'X'");
rs.next();
String type = rs.getString("constraint_type");
assertEquals("P",type); // primary key
rs.close();
rs = meta.getPrimaryKeys(null, username, "X");
rs.next();
logger.info("getting pk");
System.out.print("wtf");
int colCount = 0;
while (rs.next()) {
final String pkName = rs.getString("pk_name");
logger.info("pkName: {}", pkName);
int keySeq = rs.getShort("key_seq"); // TODO should probably be column seq
String columnName = rs.getString("column_name");
logger.warn("seq: {}, columnName: {}, keySeq, columnName");
colCount++;
}
System.out.println("colCount: " + colCount);
assertEquals(1,colCount);
}
First I query some data from user A and then I need to insert all this data to user B (user in oracle I mean) and I use Java to solve it. Below is my code:
while (ds.getResultSet().next()) {
ResultSet resultSet = ds.getResultSet();
ResultSetMetaData metaData = resultSet.getMetaData();
int count = metaData.getColumnCount();
StringBuilder sb = new StringBuilder();
sb.append("insert into ");
sb.append(tableName.toUpperCase());
sb.append("(");
for (int i = 1; i <= count; i++) {
sb.append(metaData.getColumnName(i));
if (i != count) sb.append(",");
else sb.append(")");
}
sb.append(" values(");
for (int i = 1; i <= count; i++) {
Object colValue = resultSet.getObject(i);
if (colValue == null) {
sb.append("null");
} else {
if (colValue instanceof Date) {
Date d = resultSet.getDate(i);
String dateStr = DateUtils.formatDate(d, "yyyy-MM-dd hh:mm:ss");
sb.append("to_date(");
sb.append("'");
sb.append(dateStr);
sb.append("','yyyy-MM-dd hh24:mi:ss')");
} else {
sb.append("'");
sb.append(resultSet.getObject(i));
sb.append("'");
}
}
if (i != count) sb.append(",");
else sb.append(")");
}
conn = datasource.getConnection();
System.out.println(sb.toString());
ps = conn.prepareStatement(sb.toString());
ps.execute();
}
So it works a bit, but when it inserts above 80 records oracle just collaspses, and it's warning me in the console:
Can you guys give some advice to me about this? Thanks for your time.
Do not use Java - just do it all in Oracle.
INSERT INTO b.table_name ( col1, col2, col3, col4 )
SELECT col1, col2, col3, col4
FROM a.table_name
WHERE some_column = some_value; -- Add filters if necessary
You avoid having to dynamically build the query by parsing the meta-data.
You avoid errors where you are not escaping single quotes.
Further to this, you avoid potential SQL Injection attacks where a user could enter something like the string value', (SELECT password_hash FROM users WHERE userid = 'Admin1' ) ) --
As you guys suggest, I changed my code like below:
Connection conn = DriverManager.getConnection(url, user, pwd);
PreparedStatement pspt = conn.prepareStatement("select * from SYS_DICT_TYPE");
ResultSet resultSet = pspt.executeQuery();
ResultSetMetaData metaData = resultSet.getMetaData();
int columnCount = metaData.getColumnCount();
StringBuilder sql = new StringBuilder();
sql.append("insert into TEST_SYS (");
for (int i = 1; i <= columnCount; i++) {
sql.append(metaData.getColumnName(i));
if (i != columnCount) sql.append(",");
}
sql.append(") values(");
for (int i = 1; i <= columnCount; i++) {
sql.append("?");
if (i != columnCount) sql.append(",");
}
sql.append(")");
String s = sql.toString();
PreparedStatement pspt2 = conn.prepareStatement(s);
while (resultSet.next()) {
for (int i = 1; i <= columnCount; i++) {
pspt2.setObject(i, resultSet.getObject(i));
}
pspt2.addBatch();
}
pspt2.executeBatch();
The wired thing is: At the first I build the statement end with a ';'
(the sql clause should like insert into tablename values(?,?);)
which cause ora-00933:SQL error.When I removed the ';' it worked perfectly well.Why could this happend?
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