1

I'm trying to check if row already exists, but it fails and gives me a syntax error this is the code:

public boolean checkExist(String table, String info) {
    try {
        PreparedStatement st = con.prepareStatement("SELECT EXISTS(SELECT 1 FROM " + table + " WHERE info=" + info + ")");
        return st.execute();
    } catch (SQLException e) {
        e.printStackTrace();
        return false;
    }
}

Query:

"SELECT EXISTS(SELECT 1 FROM " + table + " WHERE info=" + info + ")"

Throws: org.postgresql.util.PSQLException: ERROR: syntax error at or near ")" Position: 104

3
  • 1
    Can you print what the query string looks like after you call the function? I think that error could be caused by 'info' being empty. Commented Aug 19, 2015 at 19:20
  • that is a wrong way to use exists. How can you have a select without a from? Commented Aug 19, 2015 at 19:25
  • 1
    @vkp, in PostgreSQL, the FROM clause can be omitted here because EXISTS is a subquery expresssion which always returns a boolean. The root of the problem lays in the misuse of PreparedStatement; instead of using a bind variable, the info variable is simply conctenated into the query, but the surrounding single quotes are missing. "SELECT EXISTS(SELECT 1 FROM " + table + " WHERE info= '" + info + "')" should work, but even that would be "doing it wrong". Commented Aug 19, 2015 at 23:40

2 Answers 2

2

The problem with your query is that you're appending the value of info into the query literal, but not wrapping it within single quotes as is required in PostgreSQL. So, the query that's sent over to the DB becomes something like

SELECT EXISTS(SELECT 1 FROM myTable WHERE info=valueOfInfo)

instead of

SELECT EXISTS(SELECT 1 FROM myTable WHERE info='valueOfInfo')

The correct way to do this is to use bind variables with the PreparedStatement and only have placeholders (?) in the query literal. This way, you don't need to worry about wrapping the variable in quotes, or more importantly, the possibility of SQL injection.

Additionally, you should take care of closing the statement after use; this is easiest done with the try-with-resources statement (assuming you're on Java 7 or above). So the fixed version of your method could look something like this:

public boolean checkExist(String table, String info) {

    final String query = "SELECT EXISTS(SELECT 1 FROM " + table
            + " WHERE info = ?)";

    try (PreparedStatement st = con.prepareStatement(query,
             ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY)) {
        st.setString(1, info); // bind the variable to the placeholder
        try (ResultSet rs = st.executeQuery()) {
            if (rs.next()) {
                return rs.getBoolean(1); // EXISTS() returns a boolean
            }
        }
    } catch (SQLException e) {
        e.printStackTrace();
    }
    return false;
}
Sign up to request clarification or add additional context in comments.

3 Comments

Throws org.postgresql.util.PSQLException: Operation requires a scrollable ResultSet, but this ResultSet is FORWARD_ONLY. exception
That seems weird, because nothing in the code should be moving the cursor backwards. Could you try using PreparedStatement st = con.prepareStatement(query, ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY) instead? (Sorry I cannot test this as I don't have a PostgreSQL installation available).
Okay, that's good to know; I've edited the correction into my answer.
1

You should actually do

" SELECT 1 FROM " + table + " WHERE info=" + info + ")" "

This would return 1 when a row exists that matches the where clause.

Also, use distinct if you only need 1 returned, no matter how many rows match the where condition, like

" SELECT distinct 1 FROM " + table + " WHERE info=" + info + ")" "

1 Comment

Don't concatenate values into query. That causes sql injection vulnerability, use query parameters instead.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.