1. Home
  2. Home
  3. Documentation
  4. Query
  5. Issuing a query
Last reviewed Edit this page on GitHub

Issuing a query

Any time you want to issue SQL statements to the database, you need a Statement or PreparedStatement instance. Once you have a Statement or PreparedStatement, you can issue a query. This will return a ResultSet instance, which contains the result rows fetched by the driver (see Cursor-based fetching for how to alter this behaviour). Example 5.1, “Processing a Simple Query in JDBC” illustrates this process.

This example will issue a simple query and print out the first column of each row using a Statement.

Statement st = conn.createStatement();
ResultSet rs = st.executeQuery("SELECT * FROM mytable WHERE columnfoo = 500");
while (rs.next()) {
    System.out.print("Column 1 returned ");
    System.out.println(rs.getString(1));
}
rs.close();
st.close();

This example issues the same query as before but uses a PreparedStatement and a bind value in the query.

int foovalue = 500;
PreparedStatement st = conn.prepareStatement("SELECT * FROM mytable WHERE columnfoo = ?");
st.setInt(1, foovalue);
ResultSet rs = st.executeQuery();
while (rs.next()) {
    System.out.print("Column 1 returned ");
    System.out.println(rs.getString(1));
}
rs.close();
st.close();

Reviewed 2026-05-21 against source:PgStatement.java:280-299, PgPreparedStatement.java:92-145, Parser.java:127-144, CompositeQueryParseTest.java:54-68

The following must be considered when using the Statement or PreparedStatement interface:

  • You can use a single Statement instance as many times as you want. You could create one as soon as you open the connection and use it for the connection’s lifetime. But you have to remember that only one ResultSet can exist per Statement or PreparedStatement at a given time.

  • If you need to perform a query while processing a ResultSet, you can simply create and use another Statement.

  • If you are using threads, and several are using the database, you must use a separate Statement for each thread. Refer to DataSource and JNDI § Thread safety if you are thinking of using threads, as it covers some important points.

  • When you are done using the Statement or PreparedStatement, you should close it.

  • In JDBC, the question mark (?) is the placeholder for the positional parameters of a PreparedStatement. There are, however, a number of PostgreSQL® operators that contain a question mark. To keep such question marks in an SQL statement from being interpreted as positional parameters, use two question marks (??) as the escape sequence. You can also use this escape sequence in a Statement, but that is not required. Specifically, a single ? can be used as an operator only in a Statement.

Reviewed 2026-05-21 against source:PgStatement.java:404-427, PgStatement.java:435-499, PgResultSet.java:2271-2340, PgResultSet.java:2391-2415, PGProperty.java:136-148, PGProperty.java:688-698

The following must be considered when using the ResultSet interface:

  • Before reading any values, you must call next(). This returns true if there is a result, but more importantly, it prepares the row for processing.

  • You must close a ResultSet by calling close() once you have finished using it.

  • Once you make another query with the Statement used to create a ResultSet, the currently open ResultSet instance is closed automatically.

  • When the PreparedStatement API is used, the driver can switch supported column types to binary transfer once a statement reaches the prepareThreshold execution count. The default threshold is five query executions, and the default binaryTransfer setting enables binary transfer for supported built-in types when possible. See Server-prepared statements for details. This may cause unexpected behaviour when some methods are called. For example, getString() on non-string data types can be formatted differently once binary transfer is used.

Reviewed 2026-05-21 against source:PgStatement.java:302-323, PgStatement.java:482-490

To change data (perform an INSERT, UPDATE, or DELETE) you use the executeUpdate() method. This method is similar to the executeQuery() method used to issue a SELECT statement, but it doesn’t return a ResultSet; instead, it returns the number of rows affected by the INSERT, UPDATE, or DELETE statement. Example 5.3, “Deleting Rows in JDBC” illustrates the usage.

This example will issue a simple DELETE statement and print out the number of rows deleted.

int foovalue = 500;
PreparedStatement st = conn.prepareStatement("DELETE FROM mytable WHERE columnfoo = ?");
st.setInt(1, foovalue);
int rowsDeleted = st.executeUpdate();
System.out.println(rowsDeleted + " rows deleted");
st.close();

Reviewed 2026-05-21 against source:PgStatement.java:240-270, PgStatement.java:325-332

To create, modify, or drop a database object like a table or view, you use the execute() method. This method is similar to the method executeQuery(), but for DDL statements like DROP TABLE it normally completes without returning a ResultSet. Example 5.4, “Dropping a Table in JDBC” illustrates the usage.

This example will drop a table.

Statement st = conn.createStatement();
st.execute("DROP TABLE mytable");
st.close();