高效的SQL测试查询或验证查询,可以在所有(或大多数)数据库中使用

Rob*_*ska 136 sql connection-pooling

许多数据库连接池库提供了测试其SQL连接以实现空闲的能力.例如,JDBC池库c3p0有一个名为的属性preferredTestQuery,它以配置的间隔在连接上执行.同样,Apache Commons DBCP也有validationQuery.

我见过的许多示例 查询都是针对MySQL的,并建议使用它SELECT 1;作为测试查询的值.但是,此查询不适用于某些数据库(例如HSQLDB,SELECT 1需要一个FROM子句).

是否存在与数据库无关的查询,该查询具有同等效率,但适用于所有SQL数据库?

编辑:

如果没有(似乎是这种情况),有人可以建议一组适用于各种数据库提供程序的SQL查询吗?我的目的是以编程方式确定我可以根据我的数据库提供程序配置使用的语句.

Rob*_*ska 246

经过一些研究以及一些答案的帮助:

SELECT 1

  • H2
  • MySQL的
  • Microsoft SQL Server(根据NimChimpsky)
  • PostgreSQL的
  • SQLite的

SELECT 1 FROM DUAL

  • 神谕

SELECT 1 FROM any_existing_table WHERE 1=0

要么

SELECT 1 FROM INFORMATION_SCHEMA.SYSTEM_USERS

  • HSQLDB(使用1.8.0.10版测试)

    注意:我尝试WHERE 1=0在第二个查询中使用一个子句,但它不能作为Apache Commons DBCP的值validationQuery,因为查询不返回任何行


VALUES 1 要么 SELECT 1 FROM SYSIBM.SYSDUMMY1

SELECT 1 FROM SYSIBM.SYSDUMMY1

  • DB2

select count(*) from systables

  • Informix的

  • 我知道这是一对老夫妻多年,但您可能希望从SYSIBM.SYSDUMMY1`同时添加`VALUES 1`和`SELECT 1的Apache Derby (2认同)

Tim*_*the 16

如果您的驱动程序符合JDBC 4,则无需专用查询来测试连接.相反,有Connection.isValid来测试连接.

JDBC 4是2006年Java 6的一部分,您的驱动程序现在应该支持这一点!

着名的连接池(如HikariCP)仍然具有用于指定测试查询的配置参数,但强烈建议不要使用它:

connectionTestQuery

如果您的驱动程序支持JDBC4,我们强烈建议您不要设置此属性.这适用于不支持JDBC4 Connection.isValid()API的"遗留"数据库.这是在从池中给出连接之前执行的查询,以验证与数据库的连接是否仍然存在.再次尝试运行没有此属性的池,如果您的驱动程序不符合JDBC4,HikariCP将记录错误以通知您.默认值:无


Luk*_*der 15

jOOQ手册中关于DUAL的部分列出了 jOOQselect(inline(1))查询的以下内容:

-- Access
SELECT 1 FROM (SELECT count(*) dual FROM MSysResources) AS dual

-- BigQuery, CockroachDB, Exasol, H2, Ignite, MariaDB, MySQL, PostgreSQL, 
-- Redshift, Snowflake, SQLite, SQL Server, Sybase ASE, Vertica
SELECT 1

-- MemSQL, Oracle
SELECT 1 FROM DUAL

-- CUBRID
SELECT 1 FROM db_root

-- Db2
SELECT 1 FROM SYSIBM.DUAL

-- Derby
SELECT 1 FROM SYSIBM.SYSDUMMY1

-- Firebird
SELECT 1 FROM RDB$DATABASE

-- HANA, Sybase SQL Anywhere
SELECT 1 FROM SYS.DUMMY

-- HSQLDB
SELECT 1 FROM (VALUES(1)) AS dual(dual)

-- Informix
SELECT 1 FROM (SELECT 1 AS dual FROM systables WHERE (tabid = 1)) AS dual

-- Ingres, Teradata
SELECT 1 FROM (SELECT 1 AS "dual") AS "dual"
Run Code Online (Sandbox Code Playgroud)


Mar*_*ers 6

遗憾的是,无论数据库如何,都没有SELECT语句始终有效.

大多数数据库支持

SELECT 1
Run Code Online (Sandbox Code Playgroud)

有些数据库不支持此功能,但有一个名为DUAL的表,您可以在不需要表时使用它:

SELECT 1 FROM DUAL
Run Code Online (Sandbox Code Playgroud)

出于兼容性原因,MySQL也支持此功能,但并非所有数据库都支持.不支持上述任何一种情况的数据库的解决方法是创建一个名为DUAL的表,其中包含一行,然后上面的内容将起作用.

HSQLDB不支持以上任何一种,因此您可以创建DUAL表,或者使用:

SELECT 1 FROM any_table_that_you_know_exists_in_your_database
Run Code Online (Sandbox Code Playgroud)