views:

129

answers:

4

Many database connection pooling libraries provide the ability to test their SQL connections for idleness. For example, the JDBC pooling library c3p0 has a property called preferredTestQuery, which gets executed on the connection at configured intervals.

Many example queries I've seen are for MySQL and recommend using SELECT 1; as the value for the test query. However, this query doesn't work on some databases (e.g. HSQLDB, for which SELECT 1 expects a FROM clause).

Is there a database-agnostic query that's equivalently efficient but will work for all SQL databases?

Edit:

If there's not (which seems to be the case), can somebody suggest a set of SQL queries that will work for various database providers? My intention would be to programmatically determine a statement I can use based on my database provider configuration.

+1  A: 

Unfortunately there is no SELECT statement that will always work regardless of database.

Most databases support:

SELECT 1

Some databases don't support this but have a table called DUAL that you can use when you don't need a table:

SELECT 1 FROM DUAL

MySQL also supports this for compatibility reasons, but not all databases do. A workaround for databases that don't support either of the above is to create a table called DUAL that contains a single row, then the above will work.

HSQLDB supports neither of the above, so you can either create the DUAL table or else use:

SELECT 1 FROM any_table_that_you_know_exists_in_your_database
Mark Byers
Doesn't work for SQL Server.
Martin Smith
@Mark - Thanks for the answer. I've updated my question slightly due to your "there is no SELECT statement that will always work" statement. `SELECT 1 FROM DUAL` also doesn't work with HSQLDB.
Rob Hruska
+1, this is about where I've come with my research as well, particularly for the HSQLDB case.
Rob Hruska
which ones don't support "select 1" ? Select from dual only works oracle doesn't it ? Not sql server, or mysql at least
NimChimpsky
+1 I've given up trying to think of an RDBMS independent way!
Martin Smith
A: 

select 1 would work in sql server, not sure about the others.

Use standard ansi sql to create a table and then query from that table.

NimChimpsky
Does ansi SQL cover `create table`?
Martin Smith
yes it does. If you use ansi data types. I'd be surprised if "select 1" didn't work though.
NimChimpsky
A: 

After a little bit of research along with help from some of the answers here:

SELECT 1

  • H2
  • MySQL
  • Microsoft SQL Server (according to NimChimpsky)
  • PostgreSQL
  • SQLite

SELECT 1 FROM DUAL

  • Oracle

SELECT 1 FROM any_existing_table WHERE 1=0

  • HSQLDB
Rob Hruska
That should be "SELECT 1 FROM any_existing_table WHERE 1=0" - otherwise the call might be very slow. By the way, both SELECT 1 and SELECT 1 FROM DUAL also work with H2.
Thomas Mueller
Thanks, that's good to know. I've updated the answer.
Rob Hruska
+2  A: 

This works with most databases:

select 1 as x from information_schema.tables where 1=0

It works at least with MySQL, H2, HSQLDB (since 2.0), PostgreSQL. It doesn't work with Apache Derby. All ANSI-SQL databases are supposed to support this metadata table (I have no idea why Apache Derby doesn't). The only problem is the table might not be accessible for some users.

Thomas Mueller
I think Martin Smith suggested this in a previous answer but it didn't work for HSQLDB for some reason (and he deleted the answer). I'll take your word for it that it works with H2, though :). I'll give it a try with HSQLDB sometime today. Thanks for the response.
Rob Hruska
Yeah, tried this with HSQLDB and got the following: `Connection org.hsqldb.jdbc.jdbcConnection@1ea7d34 failed Connection test with an Exception! [query=select 1 as x from information_schema.tables where 1=0] java.sql.SQLException: Table not found: TABLES in statement [select 1 as x from information_schema.tables]` - Apparently HSQLDB uses nonstandard naming, according to http://stackoverflow.com/questions/591518/how-to-see-all-the-tables-in-an-hsqldb-database/591540#591540
Rob Hruska
Sorry, I forgot to say: it works in HSQLDB *since 2.0*
Thomas Mueller
@Thomas Mueller - Ah, that's good to know. Maybe it's just time to upgrade then. I've been testing this on 1.8.1.2.
Rob Hruska
Doesn't work in Oracle either.
FkYkko