Эффективный тестовый запрос SQL или запрос проверки, который будет работать во всех (или большинстве) баз данных



многие библиотеки пулов соединений с базами данных предоставляют возможность тестировать свои SQL-соединения на бездействие. Например, библиотека пулов JDBC c3p0 есть свойство под названием preferredTestQuery, который выполняется на соединении с заданными интервалами. Аналогично, Apache Commons DBCP имеет validationQuery.



много примерзапросы Я видел для MySQL и рекомендую использовать SELECT 1; Как значение для тестовый запрос. Однако этот запрос не работает на некоторых базах данных (например, HSQLDB, для которых SELECT 1 ждет FROM предложения).



есть ли база данных-агностический запрос, который эквивалентно эффективен, но будет работать для всех баз данных SQL?



Edit:



если нет (что, кажется, так), может ли кто-нибудь предложить набор SQL-запросов, которые будут работать для различных поставщиков баз данных? Мое намерение состояло бы в том, чтобы программно определить оператор, который я могу использовать на основе конфигурации поставщика базы данных.

1477   12  
sql

12 ответов:

после небольшого исследования вместе с помощью некоторых ответов здесь:

SELECT 1

  • H2
  • MySQL
  • Microsoft SQL Server (согласно NimChimpsky)
  • PostgreSQL
  • SQLite

SELECT 1 FROM DUAL

  • Oracle

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

Если ваш драйвер совместим с JDBC 4, нет необходимости в выделенном запросе для проверки соединений. Вместо этого есть подключение.isValid для проверки соединения.

JDBC 4 является частью Java 6 с 2006 года, и вы драйвер должен поддерживать это сейчас!

известные пулы соединений, такие как HikariCP, все еще имеют параметр конфигурации для указания тестового запроса, но настоятельно не рекомендуют его использовать:

connectionTestQuery

Если ваш драйвер поддерживает JDBC4 мы сильно не рекомендуется устанавливать это свойство. Это для" устаревших " баз данных это не поддерживает соединение JDBC4.функция IsValid() API-интерфейс. Это запрос, который будет выполнен непосредственно перед подключением к вам из пула, чтобы проверить, что подключение к базе данных по-прежнему живой. Опять же, попробуйте запустить бассейн без этого свойства, HikariCP будет регистрироваться ошибка, если ваш драйвер не соответствует JDBC4, чтобы позволить вам знать. По умолчанию: нет

к сожалению, нет оператора SELECT, который всегда будет работать независимо от базы данных.

большинство поддержка баз данных:

SELECT 1

некоторые базы данных не поддерживают это, но имеют таблицу с именем DUAL, которую вы можете использовать, когда вам не нужна таблица:

SELECT 1 FROM DUAL

MySQL также поддерживает это по соображениям совместимости, но не все базы данных делают. Обходным путем для баз данных, которые не поддерживают ни одно из вышеперечисленных, является создание таблицы с именем DUAL который содержит одну строку, то выше будет работать.

HSQLDB не поддерживает ни одно из вышеперечисленных, поэтому вы можете либо создать двойную таблицу, либо использовать:

SELECT 1 FROM any_table_that_you_know_exists_in_your_database

Я использую этот:

select max(table_catalog) as x from information_schema.tables

чтобы проверить соединение и возможность выполнения запросов (с 1 строкой в результате) для postgreSQL, MySQL и MSSQL.

для тестов с помощью select count(*), Он должен быть более эффективным в использовании select count(1), потому что * может заставить его прочитать все данные столбца.

select 1 будет работать в sql server, не уверен в других.

используйте стандартный ANSI sql для создания таблицы, а затем запрос из этой таблицы.

Я использую

Select COUNT(*) As X From INFORMATION_SCHEMA.SYSTEM_USERS Where 1=0

для hsqldb 1.8.0

предполагая, что OP хочет получить ответ Java:

с JDBC3 / Java 6 есть isValid () метод, который следует использовать, а не изобретать свой собственный метод.

разработчик драйвера должен выполнить какой-то запрос к базе данных при вызове этого идентификатора метода. Вы-как простой пользователь JDBC-не должны знать или понимать, что это за запрос. Все, что вам нужно сделать, это верить, что создатель драйвера JDBC сделал его/ее работать правильно.

как о

SELECT user()

Я использую это раньше.MySQL, H2 в порядке, я не знаю других.

только что узнал на собственном горьком опыте, что это

SELECT 1 FROM DUAL

для MaxDB, а также.

Я использую это для Жар

select 1 from RDB$RELATION_FIELDS rows 1

на MSSQL.

это помогло мне определить, если связанные серверы были живы. Используя соединение Open Query и try CATCH, чтобы поместить результаты ошибки во что-то полезное.

IF OBJECT_ID('TEMPDB..#TEST_CONNECTION') IS NOT NULL DROP TABLE #TEST_CONNECTION
IF OBJECT_ID('TEMPDB..#RESULTSERROR') IS NOT NULL DROP TABLE #RESULTSERROR
IF OBJECT_ID('TEMPDB..#RESULTSGOOD') IS NOT NULL DROP TABLE #RESULTSGOOD

DECLARE @LINKEDSERVER AS VARCHAR(25)    SET @LINKEDSERVER = 'SERVER NAME GOES HERE'
DECLARE @SQL AS VARCHAR(MAX)
DECLARE @OPENQUERY AS VARCHAR(MAX)

--IF OBJECT_ID ('dbo.usp_GetErrorInfo', 'P' ) IS NOT NULL DROP PROCEDURE usp_GetErrorInfo;  
--GO  

---- Create procedure to retrieve error information.  
--CREATE PROCEDURE dbo.usp_GetErrorInfo  
--AS  
--SELECT     
--    ERROR_NUMBER() AS ErrorNumber  
--    ,ERROR_SEVERITY() AS ErrorSeverity  
--    ,ERROR_STATE() AS ErrorState  
--    ,ERROR_PROCEDURE() AS ErrorProcedure  
--    ,ERROR_LINE() AS ErrorLine  
--    ,ERROR_MESSAGE() AS Message;  
--GO  


BEGIN TRY
SET @SQL='
SELECT 1 
'''
--SELECT @SQL
SET @OPENQUERY = 'SELECT * INTO ##TEST_CONNECTION FROM OPENQUERY(['+ @LINKEDSERVER +'],''' + @SQL + ')'
--SELECT @OPENQUERY
EXEC(@OPENQUERY)
SELECT * INTO #TEST_CONNECTION FROM ##TEST_CONNECTION
DROP TABLE ##TEST_CONNECTION
--SELECT * FROM #TEST_CONNECTION
END TRY

BEGIN CATCH
-- Execute error retrieval routine.
IF OBJECT_ID('dbo.usp_GetErrorInfo') IS NOT NULL -- IT WILL ALWAYS HAVE SOMTHING... 
    BEGIN
        CREATE TABLE #RESULTSERROR (
        [ErrorNumber]       INT
        ,[ErrorSeverity]    INT
        ,[ErrorState]       INT
        ,[ErrorProcedure]   INT
        ,[ErrorLine]        INT
        ,[Message]          NVARCHAR(MAX) 
        )
        INSERT INTO #RESULTSERROR
        EXECUTE dbo.usp_GetErrorInfo
    END
END CATCH

BEGIN 
    IF (Select ERRORNUMBER FROM #RESULTSERROR WHERE ERRORNUMBER = '1038') IS NOT NULL --'1038' FOR ME SHOWED A CONNECTION ATLEAST. 
        SELECT
        '0' AS [ErrorNumber]        
        ,'0'AS [ErrorSeverity]  
        ,'0'AS [ErrorState]     
        ,'0'AS [ErrorProcedure] 
        ,'0'AS [ErrorLine]      
        , CONCAT('CONNECTION IS UP ON ', @LINKEDSERVER) AS [Message]            
    ELSE 
        SELECT * FROM #RESULTSERROR
END

docs.microsoft.com

Comments

    Ничего не найдено.