Wydajne zapytanie testowe SQL lub zapytanie walidacyjne, które będzie działać we wszystkich (lub większości) bazach danych

Wiele bibliotek łączenia baz danych zapewnia możliwość testowania swoich połączeń SQL pod kątem bezczynności. Na przykład Biblioteka poolingowa JDBC c3p0 ma właściwość o nazwie preferredTestQuery, który jest wykonywany na połączeniu w skonfigurowanych odstępach czasu. Podobnie Apache Commons DBCP ma validationQuery.

Wiele przykład zapytania widziałem są dla MySQL i zalecam użycie SELECT 1; jako wartości dla zapytania testowego. Jednak to zapytanie nie działa na niektóre bazy danych (np. HSQLDB, dla których SELECT 1 oczekuje klauzuli FROM).

Czy istnieje zapytanie niezależne od bazy danych, które jest równie wydajne, ale będzie działać dla wszystkich baz danych SQL?

Edit:

Jeśli nie ma (co wydaje się mieć miejsce), czy ktoś może zaproponować zestaw zapytań SQL, które będą działać dla różnych dostawców baz danych? Moim zamiarem byłoby programowo określić oświadczenie, którego mogę użyć na podstawie konfiguracji dostawcy bazy danych.

Author: facundofarias, 2010-09-08

12 answers

Po odrobinie badań wraz z pomocą niektórych z odpowiedzi tutaj:

SELECT 1

  • H2
  • MySQL
  • Microsoft SQL Server (zgodnie z NimChimpsky)
  • PostgreSQL
  • SQLite

SELECT 1 FROM DUAL

  • Wyrocznia

SELECT 1 FROM any_existing_table WHERE 1=0

Lub

SELECT 1 FROM INFORMATION_SCHEMA.SYSTEM_USERS

  • HSQLDB (testowane z wersją 1.8.0.10)

    Uwaga: próbowałem użyć WHERE 1=0 klauzula na drugim zapytaniu, ale nie działała jako wartość dla Apache Commons DBCP validationQuery, ponieważ zapytanie nie zwraca żadnych wierszy


VALUES 1 lub SELECT 1 FROM SYSIBM.SYSDUMMY1

SELECT 1 FROM SYSIBM.SYSDUMMY1

  • DB2

select count(*) from systables

  • Informix
 209
Author: Rob Hruska,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 12:02:59

Jeśli twój Sterownik jest zgodny z JDBC 4, nie ma potrzeby wysyłania dedykowanego zapytania do testowania połączeń. Zamiast tego istnieje Połączenie.isValid do testowania połączenia.

JDBC 4 jest częścią Javy 6 z 2006 roku i powinieneś już to obsługiwać!

Słynne pule połączeń, takie jak HikariCP, nadal mają parametr config do określenia zapytania testowego, ale zdecydowanie odradzam korzystanie z niego:

ConnectionTestQuery

Jeśli Twój sterownik obsługuje JDBC4 we mocno nie zaleca się ustawiania tej właściwości. To jest dla" starszych " baz danych które nie obsługują połączenia JDBC4.API isValid (). To jest zapytanie, które zostanie wykonane tuż przed nawiązaniem połączenia z puli, aby potwierdzić, że połączenie z bazą danych jest nadal / align = "left" / Jeszcze raz spróbuj uruchomić basen bez tej właściwości, HikariCP zarejestruje błąd, jeśli sterownik nie jest zgodny z JDBC4, aby umożliwić Ci wiedzieć. Default: none

 9
Author: Tim Büthe,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-02-08 12:45:33

Niestety nie ma instrukcji SELECT, która zawsze będzie działać niezależnie od bazy danych.

Większość obsługa baz danych:

SELECT 1

Niektóre bazy danych tego nie obsługują, ale mają tabelę o nazwie DUAL, której możesz użyć, gdy nie potrzebujesz tabeli:

SELECT 1 FROM DUAL

MySQL obsługuje to również ze względu na kompatybilność, ale nie wszystkie bazy danych tak. Obejściem dla baz danych, które nie obsługują żadnego z powyższych, jest utworzenie tabeli o nazwie DUAL, która zawiera pojedynczy wiersz, a następnie powyższe zadziała.

HSQLDB nie obsługuje żadnego z powyższych, więc możesz utworzyć podwójną tabelę lub użyć:

SELECT 1 FROM any_table_that_you_know_exists_in_your_database
 5
Author: Mark Byers,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-09-08 14:40:15

Używam tego:

select max(table_catalog) as x from information_schema.tables

Aby sprawdzić połączenie i możliwość uruchamiania zapytań (z 1 wierszem jako wynikiem) dla postgreSQL, MySQL i MSSQL.

 2
Author: Wojciechk,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-12-28 10:05:52

W przypadku testów z użyciem select count(*), powinno być bardziej efektywne użycie select count(1), Ponieważ * może spowodować, że odczyta wszystkie dane kolumn.

 2
Author: NateN,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-02-04 20:08:43

select 1 działa w SQL serverze, nie jestem pewien co do pozostałych.

Użyj standardowego ansi sql do utworzenia tabeli, a następnie zapytanie z tej tabeli.

 1
Author: NimChimpsky,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-09-08 14:21:19

Używam

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

Dla hsqldb 1.8.0

 1
Author: thinkbase,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-04-19 18:45:02

Zakładając, że OP chce odpowiedzi Javy:

Od JDBC3 / Java 6 istnieje metoda isValid () , która powinna być używana zamiast wymyślania własnej metody.

Wykonawca drivera jest wymagany do wykonania pewnego rodzaju zapytania z bazą danych, gdy wywołał ten identyfikator metody. Ty-jako zwykły użytkownik JDBC-nie musisz wiedzieć ani rozumieć, czym jest to zapytanie. Wszystko, co musisz zrobić, to zaufać, że twórca sterownika JDBC wykonał swoją pracę prawidłowo.

 1
Author: peterh,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-01-21 11:31:19

A może

SELECT user()
Używam tego wcześniej.MySQL, H2 jest OK, nie znam innych.
 1
Author: wener,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-11-21 08:27:09

Właśnie dowiedziałem się, że to jest trudne

SELECT 1 FROM DUAL

Również dla MaxDB.

 1
Author: Lars Decker,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-10-25 12:56:37

Używam tego do Firebird

select 1 from RDB$RELATION_FIELDS rows 1
 0
Author: claudsan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-01-20 12:30:01

Dla MSSQL .

To pomogło mi ustalić, czy połączone serwery żyły. Korzystanie z połączenia otwartego zapytania i spróbuj złapać, aby umieścić wyniki błędu w czymś użytecznym.
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

 0
Author: DeFlanko,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-04-12 18:12:59