简体   繁体   中英

JDBC query throwing syntax error

Basically, what this is supposed to do is run one query, read in all the values from one column, and then run some other queries based off of those values. It turns the values into a SQL array of integers and passes that as a parameter to the statements for the other queries, but when they execute, it throws "syntax error at or near "$1" Position: 87"

Example of the queries:

"SELECT foo.id, bar.* "
+ "FROM foo, bar y "
+ "WHERE foo.baz = bar.baz and foo.id IN ? "
+ "GROUP BY foo.id";

And the parameter-setting bit (result is an arraylist of the column's data):

    Integer[] data = result.toArray(new Integer[result.size()]);
    Array array = connection.createArrayOf("INTEGER", data);

    statement.clearParameters();
    statement.setArray(1, array);

(code is genericized because this is for homework)

The IN operator requires the use of a list of expressions put between parentheses: in (1,2,3) . A ? place holder is only usable for a single scalar value (a number, a string).

If you want to pass the list of IDs as an array you need to change the SQL so that the place holder "accepts" an array:

SELECT foo.id, bar.*
FROM foo
  JOIN bar y ON foo.baz = bar.baz
WHERE and foo.id = ANY (?) 
GROUP BY foo.id

Note that I also changed your old-style implicit join in the WHERE clause to the modern explicit JOIN (but that doesn't matter for your question).

With the above syntax you can pass an array with a list of ids.

The next problem you will get is that "INTEGER" isn't a valid data type in Postgres. The type name is passed "as is" and data types are in lower case in Postgres. So you need to use:

Array array = connection.createArrayOf("integer", data);

Basically, what this is supposed to do is run one query, read in all the values from one column, and then run some other queries based off of those values

Why don't you do that in a single statement?

SELECT foo.id, bar.*
FROM foo
  JOIN bar y ON foo.baz = bar.baz
WHERE and foo.id IN (SELECT some_column FROM ...) --<< this is your "first query"
GROUP BY foo.id

That is almost always better than running two separate statements.


Unrelated:

The group by foo.id seems unnecessary as you don't use any aggregate functions. And it won't work unless foo.id is the primary key of the foo table.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM