ResultSet.next() Throwing SQLException: Result Set Closed - java

I've tried to debug the code and read the Oracle doc and I don't see any reason why the result set would be closed.
Statement statement = DatabaseConnector.connect();
String sql = "Select * from Room where Room_Type like '*"+roomType+"*' "+availability;
boolean foundResults = statement.execute(sql);
if(foundResults){
ResultSet rs = statement.getResultSet();
StringBuilder row = new StringBuilder();
if(rs!=null){
while(rs.next()){

RE: SQLException
I'm not quite sure what DatabaseConnector is supposed to do in the question code, but the following test code works for me.
RE: Wildcard character
When using the LIKE operator in a query from within the Access application itself then the asterisk * is the wildcard character to use. When querying an ACE (Access) database from some other application one needs to use the "standard" percent % wildcard character. Note that the following code uses %; using * won't work here.
import java.sql.*;
public class JDBCQuery {
public static void main( String args[] )
{
try
{
Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");
Connection conn = DriverManager.getConnection(
"jdbc:odbc:Driver={Microsoft Access Driver (*.mdb, *.accdb)};" +
"Dbq=C:\\Users\\Public\\Database1.accdb;");
String RoomTypeToMatch = "suite";
PreparedStatement s = conn.prepareStatement(
"SELECT Room_No, Room_Type " +
"FROM Room WHERE Room_Type LIKE ?"
);
s.setString(1, "%" + RoomTypeToMatch + "%");
s.execute();
ResultSet rs = s.getResultSet();
if (rs!=null)
{
while (rs.next())
{
System.out.println("[Room_No]: " + rs.getString(1) +
", [Room_Type]: " + rs.getString(2));
}
}
s.close();
conn.close();
}
catch( Exception e ) {
e.printStackTrace();
}
}
}

SQL LIKE wildcard charcaters are represented as % not *
String sql =
"Select * from Room where Room_Type like '%"+roomType+ "%' "+availability;
Aside: Always use a PreparedStatement to project against SQL Injection attacks

Related

jdbc oracle 11g PreparedStatement not producing results

I am trying fetch data based on a condition on committee column using jdbc.Using Statement it produces the desired result but using PreparedStatement it does not.I cannot figure out what has gone wrong.Kindly help.Here is both the programs one using Statement and the other one using PreparedStatement and my table structure as well
import java.sql.*;
class SelectPrepared {
public static void main(String args[]) {
try {
Class.forName("oracle.jdbc.driver.OracleDriver");
Connection con = DriverManager.getConnection("jdbc:oracle:thin:#localhost:1521:xe", "abcd","abcd");
String sql = "select * from tatuserinfo where committee = 'GENERAL'";
Statement stmt = con.createStatement();
// stmt.setString(1,"GENERAL");//1 specifies the first parameter in the query
ResultSet myRs = stmt.executeQuery(sql);
while (myRs.next()) {
System.out.println(myRs.getString(1) + myRs.getString(2) + myRs.getString(3) + myRs.getString(4)
+ myRs.getString(5) + myRs.getString(6) + myRs.getString(7) + myRs.getString(8));
}
con.close();
} catch (Exception e) {
System.out.println(e);
}
}
}
import java.sql.*;
class SelectPreparedOne {
public static void main(String args[]) {
try {
Class.forName("oracle.jdbc.driver.OracleDriver");
String s = "GENERAL";
Connection con = DriverManager.getConnection("jdbc:oracle:thin:#localhost:1521:xe", "abcd","abcd");
String sql = "select * from tatuserinfo where committee = ?";
PreparedStatement stmt = con.prepareStatement(sql);
stmt.setString(1, s);// 1 specifies the first parameter in the query
ResultSet myRs = stmt.executeQuery();
while (myRs.next()) {
System.out.println(myRs.getString(1) + myRs.getString(2) + myRs.getString(3) + myRs.getString(4)
+ myRs.getString(5) + myRs.getString(6) + myRs.getString(7) + myRs.getString(8));
}
con.close();
} catch (Exception e) {
System.out.println(e);
}
}
}
Table structure
USERNAME VARCHAR2(40)
PASSWORD VARCHAR2(40)
ROLE VARCHAR2(40)
NAME VARCHAR2(40)
DESIGNATION VARCHAR2(40)
DEPARTMENT VARCHAR2(40)
EMAILID VARCHAR2(40)
COMMITTEE CHAR(15)
TL/DR: don't use char use varchar2
CHAR(15) gets blank padded to 15 characters, so the column contains the value 'GENERAL ' and that's not equal to the supplied value of 'GENERAL'
The correct fix is to change the column to VARCHAR2(15)
An intermediate ugly workaround (until you fix the column definition) is to use trim:
where trim(committee) = ?;

How can I only get 1 element from a SQL Database?

I have a small problem. I wrote a method in which I have an SQL query that should output a correct string after 2 parameters. When debugging, however, the result is not the right element. I don't know why this happens.
public static String findRightTemplate(String user_name, int template_id)
throws Exception {
Connection conn = DriverManager.getConnection(
"xxx", "xxx", "xxx");
Statement st = conn.createStatement();
st = conn.createStatement();
ResultSet rs = st.executeQuery(
"SELECT template FROM templates " +
"where template_id=template_id AND user_name=user_name"
);
String temp="";
while(rs.next())
{
temp=rs.getString("template");
}
rs.close();
st.close();
conn.close();
I ask for the username and template_id and I just want to get an element out of the template column.
The SQL query is correct. I've already tested that. But it seems that the query runs through all elements with the same username. As a result, I only get the last element and not the right one.
UPDATE
Currently you do not use the method parameters inside your query. As already suggested you should use a PreparedStatement to fix that. You should basically do the following:
public static String findRightTemplate(String userName, int templateId) throws SQLException {
try (final Connection connection = DriverManager.getConnection("...")) {
final PreparedStatement preparedStatement = connection.prepareStatement(
"SELECT template " +
"FROM templates " +
"WHERE user_name = ? " +
"AND template_id = ? " +
"LIMIT 1"
);
preparedStatement.setString(1, userName);
preparedStatement.setInt(2, templateId);
final ResultSet resultSet = preparedStatement.executeQuery();
if (resultSet.next()) {
return resultSet.getString(1);
}
}
return null;
}
If you do not use a PreparedStatement and build the query manually as suggested in the comments your application could be vulnerable to SQL injection attacks.

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.

Using two LIKE's in different columnName?

I'm trying to make a search function in JTable in my program, but i got sql syntax error when i use this syntax. I've been read much question and answer in this problem and i never got the right syntax. Hope you can help me.
private void fillTable(String keyword) throws SQLException{
if (!keyword.equals("")){
try( Connection con = DriverManager.getConnection
("jdbc:mysql://localhost:3306/inventory?zero"
+ "DateTimeBehavior=convertToNull","root","");
Statement stmt = con.createStatement();
ResultSet rs = stmt.executeQuery("SELECT * FROM basis"
+ "WHERE barcode LIKE '%"+keyword+"%' or "
+ "namaProduk LIKE '% "+keyword+" %'");
){
jTable1.setModel(buildTableModel(rs));
}
}
else fillTable();
}
You are missing 1 space between basis and WHERE (reason for the syntax error).
There is 1 unwanted space between % and your keyword (makes your query irrelevant).
private void fillTable(String keyword) throws SQLException{
if (!keyword.equals("")){
try( Connection con = DriverManager.getConnection
("jdbc:mysql://localhost:3306/inventory?zero"
+ "DateTimeBehavior=convertToNull","root","");
Statement stmt = con.createStatement();
ResultSet rs = stmt.executeQuery("SELECT * FROM basis "
+ "WHERE barcode LIKE '%"+keyword+"%' or "
+ "namaProduk LIKE '%"+keyword+" %'");
){
jTable1.setModel(buildTableModel(rs));
}
}
else fillTable();
}
What I can see here is that there's a space missing behind the table name "basis". Generally, you should test your SQL statements manually via an existing DB client and then copy them into your code.
If you're open to tools that will ease your pain, try QueryDSL.

Java JDBC Incorrect Syntax Error

I have this method to load the objects, however when I am running the sql code it is giving me a Syntax error.
public void loadObjects() {
Statement s = setConnection();
// Add Administrators
try {
ResultSet r = s.executeQuery("SELECT * FROM Administrator;");
while (r.next()) {
Administrator getUser = new Administrator();
getUser.ID = r.getString(2);
ResultSet r2 = s.executeQuery("SELECT * FROM Userx WHERE ID= {" + getUser.ID + "};");
getUser.name = r2.getString(2);
getUser.surname = r2.getString(3);
getUser.PIN = r2.getLong(4);
JBDeveloping.users.administrators.add(getUser);
}
} catch (Exception e) {
System.out.println(e);
}
}
I have tried inserting the curly braces as stated in other questions, but I am either doing it wrong or it doesn't work.
This method should be able to load all administrators but I believe it is only inserting half of the ID.
The ID that it gets, consists of numbers and char; example "26315G"
the Error -
com.microsoft.sqlserver.jdbc.SQLServerException: Incorrect syntax near '26315'.
Edit -
private java.sql.Connection setConnection(){
java.sql.Connection con = null;
try {
Class.forName("com.microsoft.sqlserver.jdbc.SQLServerDriver");
String url = "jdbc:sqlserver://" + host + ";DatabaseName=" + database + ";integratedSecurity=true;";
con = DriverManager.getConnection(url, username, password);
} catch(Exception e) {
System.out.println(e);
}
return con;
}
public void loadObjects() {
java.sql.Connection con = setConnection();
// Add Administrators
try {
PreparedStatement sql = con.prepareStatement("SELECT * FROM Administrator");
ResultSet rs = sql.executeQuery();
while (rs.next()) {
Administrator getUser = new Administrator();
getUser.ID = rs.getString(2);
PreparedStatement sql2 = con.prepareStatement("SELECT * FROM Userx WHERE ID=?");
sql2.setString(1, getUser.ID);
ResultSet r2 = sql2.executeQuery();
getUser.name = r2.getString(2);
getUser.surname = r2.getString(3);
getUser.PIN = r2.getLong(4);
JBDeveloping.users.administrators.add(getUser);
}
} catch (Exception e) {
System.out.println(e);
}
}
Actually it is not the way to do that in JDBC. That way, even if you sort your syntax error, your code is prone to sql injection attacks.
The right way would be:
// Let's say your user id is an integer
PreparedStatement stmt = connection.prepareStatement("select * from userx where id=?");
stmt.setInt(1, getUser.ID);
ResultSet rs = stmt.executeQuery();
This way you are guarded against any attempt to inject SQL in your application request parameters
First of all: if you use concurrently result-sets, you must use separate statements for each one of them (you can not share Statement s between two r and r2). And more, you lack r2.next() before reading from it.
On the other hand: it would be much more effective to use PreparedStatement in the loop that to rewrite the query all the time.
So I'd go for something like this:
public void loadObjects() {
try (
Statement st = getConnection().createStatement();
//- As you read (later) only id, then why to use '*' in this query? It only takes up resources.
ResultSet rs = st.executeQuery("SELECT id FROM Administrator");
PreparedStatement ps = getConnection().prepareStatement("SELECT * FROM Userx WHERE ID = ?");
ResultSet r2 = null;
) {
while (rs.next()) {
Administrator user = new Administrator();
user.ID = rs.getString("id");
ps.setInt(1, user.ID);
r2 = ps.executeQuery();
if (r2.next()) {
user.name = r2.getString(2);
user.surname = r2.getString(3);
user.PIN = r2.getLong(4);
JBDeveloping.users.administrators.add(user);
}
else {
System.out.println("User with ID=" + user.ID + " was not found.");
}
}
}
catch (Exception x) {
x.printStacktrace();
}
}
Please note use of Java7 auto-close feature (you didn't close resources in you code). And last note: until you are not separating statements in your queries, as to JDBC documentation, you should not place ';' at the end of statements (in all cases you shouldn't place ';' as the last character in you query string).
You should not use {} and you should not append parameters into a SQL query like this.
Remove the curly braces and use PreparedStatement instead.
see http://www.unixwiz.net/techtips/sql-injection.html

Categories