कुशल SQL परीक्षण क्वेरी या सत्यापन क्वेरी जो सभी (या अधिकांश) डेटाबेस में काम करेगी


148

कई डेटाबेस कनेक्शन पूलिंग लाइब्रेरी आलस्य के लिए अपने SQL कनेक्शन का परीक्षण करने की क्षमता प्रदान करते हैं। उदाहरण के लिए, JDBC पूलिंग लाइब्रेरी c3p0 में एक संपत्ति होती है preferredTestQuery, जिसे कॉन्फ़िगर किए गए अंतराल पर कनेक्शन पर निष्पादित किया जाता है। इसी तरह, Apache Commons DBCP है validationQuery

मेरे द्वारा देखे गए कई उदाहरण क्वेरी MySQL के SELECT 1;लिए हैं और परीक्षण क्वेरी के लिए मान के रूप में उपयोग करने की सलाह देते हैं । हालाँकि, यह क्वेरी कुछ डेटाबेस पर काम नहीं करती है (उदाहरण के लिए HSQLDB, जिसके लिए SELECT 1एक FROMखंड की उम्मीद है )।

क्या एक डेटाबेस-एग्नॉस्टिक क्वेरी है जो समान रूप से कुशल है लेकिन सभी SQL डेटाबेस के लिए काम करेगी?

संपादित करें:

यदि ऐसा नहीं है (जो ऐसा प्रतीत होता है), तो क्या कोई SQL प्रश्नों का एक सेट सुझा सकता है जो विभिन्न डेटाबेस प्रदाताओं के लिए काम करेगा? मेरा इरादा प्रोग्रामेटिकली यह निर्धारित करना होगा कि मैं अपने डेटाबेस प्रदाता कॉन्फ़िगरेशन के आधार पर क्या उपयोग कर सकता हूं।



1
नोट: परीक्षण क्वेरी को कॉन्फ़िगर करने की अब कोई आवश्यकता नहीं है, नीचे मेरा उत्तर देखें
टिम बुथ

जवाबों:


274

यहाँ कुछ उत्तरों की मदद के साथ-साथ थोड़ी खोजबीन के बाद:

SELECT 1

  • एच 2
  • माई एसक्यूएल
  • Microsoft SQL सर्वर ( 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दूसरी क्वेरी पर एक खंड का उपयोग करने की कोशिश की , लेकिन यह अपाचे कॉमन्स DBCP के लिए एक मूल्य के रूप में काम नहीं किया validationQuery, क्योंकि क्वेरी किसी भी पंक्तियों को वापस नहीं करती है


VALUES 1 या SELECT 1 FROM SYSIBM.SYSDUMMY1

SELECT 1 FROM SYSIBM.SYSDUMMY1

  • डीबी 2

select count(*) from systables

  • इन्फोर्मिक्स

वह "SELECT 1 FROM any_existing_table WHERE 1 = 0" होना चाहिए - अन्यथा कॉल बहुत धीमा हो सकता है। वैसे, SELECT 1 और SELECT 1 FROM DUAL दोनों ही H2 के साथ काम करते हैं।
थॉमस मुलर

2
मुझे पता है कि यह कुछ साल पुराना है लेकिन आप अपाचे डर्बी VALUES 1और दोनों को जोड़ना चाह सकते हैंSELECT 1 FROM SYSIBM.SYSDUMMY1
Daiscog

ओपी मानकर एक जावा उत्तर चाहता है: मेरा मानना ​​है कि जावा 6 के साथ यह उत्तर अब पुराना हो चुका है। इस पृष्ठ पर कहीं और मेरा जवाब देखें।
पेट्र

आप इन दोनों को अपने उत्तर में जोड़ सकते हैं, DB2: "Sysibm.sysdummy1 से वर्तमान तिथि का चयन करें" Informix: "सिस्टेबल्स से गिनती (*) का चयन करें"
माइकल

@ मिचेल यदि आप एक संपादन का सुझाव देना चाहते हैं, तो मैं इसे स्वीकार करूंगा। साथ ही, आपको इसके लिए युगल प्रतिनिधि अंक मिलेंगे।
रोब ह्रस्का

22

यदि आपका ड्राइवर JDBC 4 अनुरूप है, तो कनेक्शन का परीक्षण करने के लिए एक समर्पित क्वेरी की आवश्यकता नहीं है। इसके बजाय, कनेक्शन का परीक्षण करने के लिए Connection.isValid है।

JDBC 4 2006 से जावा 6 का हिस्सा है और अब तक आपको ड्राइवर को इसका समर्थन करना चाहिए!

प्रसिद्ध कनेक्शन पूल, जैसे HikariCP, अभी भी एक परीक्षण प्रश्न निर्दिष्ट करने के लिए एक विन्यास पैरामीटर है, लेकिन इसका उपयोग करने के लिए दृढ़ता से हतोत्साहित करते हैं:

🔠connectionTestQuery

यदि आपका ड्राइवर JDBC4 का समर्थन करता है तो हम दृढ़ता से इस संपत्ति को स्थापित नहीं करने की सलाह देते हैं। यह "विरासत" डेटाबेस के लिए है जो JDBC4 Connection.isValid () API का समर्थन नहीं करता है। यह वह क्वेरी है जिसे एक कनेक्शन से ठीक पहले क्रियान्वित किया जाएगा जो आपको पूल से यह प्रमाणित करने के लिए दिया जाता है कि डेटाबेस से कनेक्शन अभी भी जीवित है। फिर, इस संपत्ति के बिना पूल चलाने की कोशिश करें, अगर आपका ड्राइवर आपको बताने के लिए JDBC4 अनुरूप नहीं है तो HikariCP एक त्रुटि दर्ज करेगा। डिफ़ॉल्ट: कोई नहीं


9

दुर्भाग्यवश कोई भी सेलेक्ट स्टेटमेंट नहीं है जो डेटाबेस की परवाह किए बिना हमेशा काम करेगा।

अधिकांश डेटाबेस समर्थन करते हैं:

SELECT 1

कुछ डेटाबेस इसका समर्थन नहीं करते हैं, लेकिन DUAL नामक एक तालिका है जिसका उपयोग आप तब कर सकते हैं जब आपको तालिका की आवश्यकता नहीं होती है:

SELECT 1 FROM DUAL

MySQL संगतता कारणों के लिए भी इसका समर्थन करता है, लेकिन सभी डेटाबेस ऐसा नहीं करते हैं। डेटाबेस के लिए एक वर्कअराउंड जो उपरोक्त दोनों में से किसी का समर्थन नहीं करता है, डीयूएल नामक एक तालिका बनाना है जिसमें एक पंक्ति होती है, फिर उपरोक्त कार्य करेगा।

HSQLDB उपरोक्त दोनों में से किसी का भी समर्थन नहीं करता है, इसलिए आप या तो DUAL तालिका बना सकते हैं या अन्य उपयोग कर सकते हैं:

SELECT 1 FROM any_table_that_you_know_exists_in_your_database

जवाब के लिए धन्यवाद। मैंने आपके प्रश्न के कारण थोड़ा सा अपडेट किया है "कोई भी सेलेक्ट स्टेटमेंट नहीं है जो हमेशा काम करेगा" स्टेटमेंट। SELECT 1 FROM DUALHSQLDB के साथ भी काम नहीं करता है।
रोब ह्रस्का

1
+1, यह उस जगह के बारे में है जहाँ मैं अपने शोध के साथ आया हूँ, विशेष रूप से HSQLDB मामले के लिए।
रोब हरसुका

जो "1 का चयन करें" का समर्थन नहीं करते हैं? दोहरे से चयन केवल काम करता है यह नहीं है? नहीं sql सर्वर, या mysql कम से कम
NimChimpsky

+1 मैंने आरडीबीएमएस के स्वतंत्र तरीके से सोचने की कोशिश छोड़ दी है!
मार्टिन स्मिथ

2

मैं इस एक का उपयोग करें:

select max(table_catalog) as x from information_schema.tables

PostgreSQL, MySQL और MSSQL के लिए कनेक्शन (1 पंक्ति के साथ क्वेरी) चलाने के लिए कनेक्शन और क्षमता की जांच करने के लिए।


2

मैं उपयोग करता हूं

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

hsqldb 1.8.0 के लिए


2

उपयोग करने वाले परीक्षणों के लिए select count(*), इसका उपयोग करने के लिए अधिक कुशल होना चाहिए select count(1)क्योंकि *यह सभी कॉलम डेटा को पढ़ने का कारण बन सकता है।


1

select 1 SQL सर्वर में काम करेगा, दूसरों के बारे में निश्चित नहीं है।

तालिका बनाने और फिर उस तालिका से क्वेरी करने के लिए मानक एएनआई sql का उपयोग करें।


क्या एसीसी एसक्यूएल कवर करता है create table?
मार्टिन स्मिथ

हाँ यह करता है। यदि आप एनी डेटा प्रकारों का उपयोग करते हैं। मुझे आश्चर्य होगा अगर "1 का चयन करें" हालांकि काम नहीं किया।
निमचम्प्सकी

1

ओपी मानकर एक जावा उत्तर चाहता है:

JDBC3 / Java 6 के रूप में वहाँ isValid () विधि है जिसका उपयोग किसी की खुद की विधि का आविष्कार करने के बजाय किया जाना चाहिए।

ड्राइवर के कार्यान्वयनकर्ता को डेटाबेस के खिलाफ किसी प्रकार के क्वेरी को निष्पादित करने की आवश्यकता होती है जब यह विधि आईडी कहा जाता है। आप - केवल JDBC उपयोगकर्ता के रूप में - यह जानना या समझना नहीं है कि यह क्वेरी क्या है। आपको बस यह विश्वास करना है कि JDBC ड्राइवर के निर्माता ने अपना काम ठीक से किया है।


2
मेरा मानना ​​है कि ओपी एक कंटेनर के कनेक्शन पूल कॉन्फ़िगरेशन के लिए सत्यापन क्वेरी के बारे में बात कर रहा है, न कि प्रोग्रामिक रूप से। उदाहरण के लिए टॉमकैट के संदर्भ में। xml, जहाँ आप संसाधन सेट करते हैं, यह एक सत्यापन लेता है जो टॉमकैट एक कनेक्शन को मान्य करने के लिए उपयोग करता है। टॉमक्वाट को अपने आप को अमान्य () का लाभ लेने के लिए बदलना होगा। यह ऐसा कुछ नहीं है जिसे ओपी नियंत्रित कर सकता है।
माइकल

यह भी ध्यान देने योग्य है कि "जेडीबीसी चालक के निर्माता ने अपना काम ठीक से किया है" वास्तव में गारंटी नहीं है। मैंने अभी पाया कि न तो Postgres, HSQLDB, और न ही H2 ने इस पद्धति को लागू करने के लिए परेशान किया है, इसलिए यह हमेशा एक अपवाद उठाएगा।
अकरॉय

1

कैसा रहेगा

SELECT user()

मैं इससे पहले इसका इस्तेमाल करता हूं। MSQL, H2 ठीक है, मैं दूसरों को नहीं जानता।


1

बस यह पता चला कि यह कठिन तरीका है

SELECT 1 FROM DUAL

मैक्सबीडी के लिए भी।


यह प्रश्न का उत्तर प्रदान नहीं करता है। एक बार आपके पास पर्याप्त प्रतिष्ठा होने पर आप किसी भी पोस्ट पर टिप्पणी करने में सक्षम होंगे ; इसके बजाय, ऐसे उत्तर प्रदान करें जिन्हें पूछने वाले से स्पष्टीकरण की आवश्यकता न हो । - समीक्षा से
पीटर ब्रिटैन

मुझे यह नहीं मिला, यह स्वीकार किए गए उत्तर के लिए मूल्य जोड़ता है, तो समस्या कहां है?
लार्स डेकर

और जैसा कि आपने उल्लेख किया है: जैसा कि मैंने स्वीकार किए गए उत्तर पर टिप्पणी नहीं की है, इसलिए मैंने इसे यहां एक उत्तर के रूप में रखा है। इसलिए बेहतर है कि एक पोस्ट न लिखें, हालांकि यह सिर्फ प्रतिष्ठा के कारण सहायक हो सकता है?
लार्स डेकर

टीबीएच, यह एक करीबी कॉल है ... जवाब की नकल करने के बजाय, यह मूल उत्तर पर एक टिप्पणी होनी चाहिए । असफल होने पर, आप मूल को सुझाए गए संपादन कर सकते थे।
पीटर ब्रिटैन

1

ओरेकल के लिए उच्च प्रदर्शन क्वेरी होगी

select 'X' from <your_small_table> where <primay_key_coulmn> = <some_value>

यह प्रदर्शन के नजरिए से है।


0

मैं इसका उपयोग Firebird के लिए करता हूं

select 1 from RDB$RELATION_FIELDS rows 1

0

के लिए MSSQL

यदि लिंक किए गए सर्वर जीवित थे, तो इससे मुझे यह निर्धारित करने में मदद मिली। ओपन क्वैरी कनेक्शन और टीआरवाई कैटच का उपयोग करके त्रुटि के परिणामों को कुछ उपयोगी बनाने के लिए।

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

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.