mysql - तालिका से चयन 1 का क्या मतलब है?




plsql (13)

select 1 from table कुछ डेटाबेस द्वारा किसी कनेक्शन के परीक्षण के लिए एक जांच के रूप में किया जाता है ताकि यह देखने के लिए कि यह जीवित है या नहीं, अक्सर कनेक्शन पूल से कनेक्शन को पुनर्प्राप्त करने या वापस करने पर उपयोग किया जाता है।

मैंने इस तरह के कुछ के साथ कई सवाल देखा है ..

Select 1  
From table

यह 1 का क्या अर्थ है और इसे कैसे निष्पादित किया जाएगा और यह क्या वापस आएगा? कृपया मुझे यह भी मार्गदर्शन करें कि किस प्रकार के मामलों का उपयोग किया जा सकता है ???

अग्रिम में धन्यवाद


थोड़ा और विशिष्ट होने के लिए, आप इसका उपयोग करने के लिए उपयोग करेंगे

SELECT 1 FROM MyUserTable WHERE user_id = 33487

करने के बजाय

SELECT * FROM MyUserTable WHERE user_id = 33487

क्योंकि आप परिणामों को देखने की परवाह नहीं करते हैं। डेटाबेस 1 के लिए नंबर 1 के लिए पूछना बहुत आसान है (क्योंकि इसे कोई लुक-अप नहीं करना है)।


तालिका में प्रत्येक रिकॉर्ड के लिए परिणाम 1


मुझे लगता है कि यह हमेशा एसक्यूएल इंजेक्शन में प्रयोग किया जाता है, जैसे कि:

www.urlxxxxx.com/xxxx.asp?id=99 union select 1,2,3,4,5,6,7,8,9 from database;

इन नंबरों का अनुमान लगाने के लिए उपयोग किया जा सकता है कि डेटाबेस कहां मौजूद है और आपके द्वारा निर्दिष्ट डेटाबेस के कॉलम नाम का अनुमान लगाएं। और तालिकाओं के मान।


इसका मतलब है कि आप आउटपुट के रूप में एक मान " 1 " चाहते हैं या अधिकांश समय आंतरिक क्वेरी के रूप में उपयोग किया जाता है क्योंकि किसी कारण से आप आंतरिक प्रश्नों के परिणाम के आधार पर बाहरी प्रश्नों की गणना करना चाहते हैं .. हर बार जब आप 1 का उपयोग नहीं करते हैं लेकिन आप कुछ विशिष्ट मूल्य हैं ...

यह आपको स्थिर रूप से मूल्य 1 के रूप में आउटपुट देगा।


इसका मतलब यह है कि आप तालिका से पहले कॉलम को पुनर्प्राप्त कर रहे हैं ,, का मतलब है Emply_num, Empl_no कर्मचारियों से; यहां आप कर्मचारियों से चयन 1 का उपयोग कर रहे हैं; इसका मतलब है कि आप Emply_num कॉलम को पुनर्प्राप्त कर रहे हैं। धन्यवाद


select 1 from table की प्रत्येक पंक्ति के लिए निरंतर 1 लौटाएगा। यह तब उपयोगी होता है जब आप सस्ते रूप से यह निर्धारित करना चाहते हैं कि रिकॉर्ड आपके where मेल खाता है और / या join


SELECT 1 FROM TABLE_NAME , "तालिका से 1 लौटें"। यह अपने आप पर बहुत ही अचूक है, इसलिए आमतौर पर इसका उपयोग WHERE साथ किया जाएगा और अक्सर EXISTS (@gbn नोट्स के रूप में, यह आवश्यक रूप से सर्वोत्तम अभ्यास नहीं है, हालांकि, यह ध्यान देने योग्य है, भले ही यह वास्तव में नहीं है सार्थक (कहा जाता है, मैं इसका उपयोग करूंगा क्योंकि अन्य इसका इस्तेमाल करते हैं और यह तुरंत "अधिक स्पष्ट" है। बेशक, यह एक चिपचिपा चिकन बनाम अंडा मुद्दा हो सकता है, लेकिन मैं आम तौर पर नहीं रहता))।

 SELECT * FROM TABLE1 T1 WHERE EXISTS (
     SELECT 1 FROM TABLE2 T2 WHERE T1.ID= T2.ID
 );

असल में, उपर्युक्त तालिका 1 से सबकुछ वापस कर देगा जिसमें तालिका 2 से संबंधित आईडी है। (यह एक स्पष्ट उदाहरण है, जाहिर है, लेकिन मेरा मानना ​​है कि यह विचार व्यक्त करता है। व्यक्तिगत रूप से, मैं शायद उपरोक्त के रूप में उपरोक्त SELECT * FROM TABLE1 T1 WHERE ID IN (SELECT ID FROM TABLE2); जैसा कि मैंने देखा है कि एफएआर पाठक को अधिक स्पष्ट है जब तक कि परिस्थितित्मक रूप से आकर्षक कारण न हो)।

संपादित करें

वास्तव में एक ऐसा मामला है जिसे मैं अभी तक भूल गया था। उस स्थिति में जहां आप किसी बाहरी भाषा से डेटाबेस में किसी मान का अस्तित्व निर्धारित करने का प्रयास कर रहे हैं, कभी-कभी SELECT 1 FROM TABLE_NAME । यह एक व्यक्तिगत कॉलम चुनने पर महत्वपूर्ण लाभ प्रदान नहीं करता है, लेकिन, कार्यान्वयन के आधार पर, यह एक SELECT * पर पर्याप्त लाभ प्रदान कर सकता है, क्योंकि यह अक्सर ऐसा होता है कि डीबी एक भाषा में लौटने वाले अधिक कॉलम, बड़े डेटा संरचना, जिसका अर्थ यह है कि अधिक समय लिया जाएगा।


यदि आप WHERE क्लॉज के आधार पर सही या गलत जांचना चाहते हैं, तो तालिका से 1 चुनें जहां स्थिति सबसे सस्ता तरीका है।


यदि आपको नहीं पता कि आपके पास टेबल का कोई डेटा मौजूद है या नहीं, तो आप निम्न क्वेरी का उपयोग कर सकते हैं:

SELECT cons_value FROM table_name;

एक उदाहरण के लिए:

SELECT 1 FROM employee;
  1. यह एक कॉलम लौटाएगा जिसमें पंक्तियों की कुल संख्या शामिल है और सभी पंक्तियों में समान स्थिर मूल्य 1 है (इस बार यह सभी पंक्तियों के लिए 1 लौटाता है);
  2. यदि आपकी तालिका में कोई पंक्ति नहीं है तो यह कुछ भी वापस नहीं आएगी।

इसलिए, हम इस SQL ​​क्वेरी का उपयोग यह जानने के लिए करते हैं कि तालिका में कोई डेटा है या पंक्तियों की संख्या इंगित करती है कि इस तालिका में कितनी पंक्तियां मौजूद हैं।


यद्यपि यह व्यापक रूप से ज्ञात नहीं है, लेकिन एक क्वेरी में GROUP BY क्लॉज के बिना एक HAVING क्लॉज हो सकता है।

ऐसी परिस्थितियों में, HAVING क्लॉज पूरे सेट पर लागू होता है। स्पष्ट रूप से, SELECT खंड किसी भी कॉलम का संदर्भ नहीं दे सकता है, अन्यथा आप त्रुटि प्राप्त करेंगे (सही) त्रुटि प्राप्त करें, "कॉलम चयनित में अमान्य है क्योंकि यह ग्रुप बाय" में शामिल नहीं है।

इसलिए, एक शाब्दिक मान का उपयोग किया जाना चाहिए (क्योंकि SQL शून्य कॉलम के साथ परिणामसेट की अनुमति नहीं देता है - क्यों ?!) और शाब्दिक मान 1 ( INTEGER ) का उपयोग आमतौर पर किया जाता है: यदि HAVING क्लॉज TRUE मूल्यांकन करता है तो परिणामसेट एक होगा पंक्ति 1 दिखाते हुए एक कॉलम के साथ पंक्ति, अन्यथा आपको खाली सेट मिलता है।

उदाहरण: यह पता लगाने के लिए कि क्या कॉलम में एक से अधिक विशिष्ट मान हैं:

SELECT 1
  FROM tableA
HAVING MIN(colA) < MAX(colA);

यह जो करता है वह करता है - यह हमेशा पूर्णांक 1 लौटाएगा। यह जांचने के लिए प्रयोग किया जाता है कि आपके रिकॉर्ड से मेल खाने वाला रिकॉर्ड मौजूद है या नहीं।


यहां हर उत्तर समस्या का केवल एक हिस्सा शामिल है। वास्तव में, चार अलग-अलग क्वेरी पार्ट्स हैं जिन्हें हम गतिशील रूप से इसमें जोड़ सकते हैं:

  • एक स्ट्रिंग
  • एक संख्या
  • एक पहचानकर्ता
  • एक वाक्यविन्यास कीवर्ड।

और तैयार बयान उनमें से केवल दो को शामिल करता है।

लेकिन कभी-कभी हमें अपनी क्वेरी को और अधिक गतिशील बनाना पड़ता है, ऑपरेटरों या पहचानकर्ताओं को भी जोड़ना पड़ता है। तो, हमें विभिन्न सुरक्षा तकनीकों की आवश्यकता होगी।

सामान्य रूप से, इस तरह के एक संरक्षण दृष्टिकोण whitelisting पर आधारित है।

इस मामले में, प्रत्येक गतिशील पैरामीटर को आपकी स्क्रिप्ट में हार्डकोड किया जाना चाहिए और उस सेट से चुना जाना चाहिए। उदाहरण के लिए, गतिशील क्रम करने के लिए:

$orders  = array("name", "price", "qty"); // Field names
$key     = array_search($_GET['sort'], $orders)); // See if we have such a name
$orderby = $orders[$key]; // If not, first one will be set automatically. smart enuf :)
$query   = "SELECT * FROM `table` ORDER BY $orderby"; // Value is safe

हालांकि, पहचानने वालों को सुरक्षित करने का एक और तरीका है - भागना। जब तक आपके पास एक पहचानकर्ता उद्धृत किया गया हो, तब तक आप उन्हें दोगुना करके बैकटिक्स से बच सकते हैं।

एक और कदम के रूप में, हम तैयार प्लेसमेंट से कुछ प्लेसहोल्डर (क्वेरी में वास्तविक मूल्य का प्रतिनिधित्व करने के लिए प्रॉक्सी) का उपयोग करने का वास्तव में शानदार विचार उधार ले सकते हैं और एक पहचानकर्ता प्लेसहोल्डर - किसी अन्य प्रकार के प्लेसहोल्डर का आविष्कार कर सकते हैं।

इसलिए, लंबी कहानी को कम करने के लिए: यह प्लेसहोल्डर है , तैयार कथन को चांदी की बुलेट के रूप में नहीं माना जा सकता है।

इसलिए, एक सामान्य सिफारिश को तब तक phrased किया जा सकता है जब तक आप प्लेसहोल्डर (और इन प्लेसहोल्डर्स को सही तरीके से संसाधित) का उपयोग करके क्वेरी में गतिशील भागों को जोड़ रहे हैं, आप सुनिश्चित कर सकते हैं कि आपकी क्वेरी सुरक्षित है

फिर भी, एसक्यूएल सिंटैक्स कीवर्ड (जैसे AND , DESC और ऐसे) के साथ कोई समस्या है, लेकिन इस मामले में श्वेत-सूची एकमात्र दृष्टिकोण प्रतीत होती है।

अद्यतन करें

यद्यपि एसक्यूएल इंजेक्शन संरक्षण के संबंध में सर्वोत्तम प्रथाओं पर एक सामान्य समझौता है, फिर भी कई बुरे प्रथाएं भी हैं। और उनमें से कुछ PHP उपयोगकर्ताओं के दिमाग में बहुत गहराई से जड़ें हैं। उदाहरण के लिए, इस पृष्ठ पर 80 से अधिक हटाए गए उत्तरों से अधिकतर (हालांकि अधिकांश आगंतुकों के लिए अदृश्य) हैं - खराब गुणवत्ता के कारण समुदाय द्वारा हटाए गए सभी या खराब और पुरानी प्रथाओं को बढ़ावा देना। इससे भी बदतर, कुछ बुरे उत्तरों को हटाया नहीं गया है, बल्कि समृद्ध है।

उदाहरण के लिए, there(1) are(2) still(3) many(4) answers(5) , जिसमें share दिए गए share जो आपको मैन्युअल स्ट्रिंग से बचने का सुझाव देते हैं - एक पुराना दृष्टिकोण जो असुरक्षित साबित हुआ है।

या थोड़ा बेहतर जवाब है जो स्ट्रिंग स्वरूपण की एक और विधि का सुझाव देता है और यहां तक ​​कि इसे अंतिम पैनसिया के रूप में भी समझाता है। बेशक, यह नहीं है। यह विधि नियमित स्ट्रिंग स्वरूपण से बेहतर नहीं है, फिर भी यह अपनी सभी कमियों को रखती है: यह केवल स्ट्रिंग पर लागू होती है और, किसी अन्य मैन्युअल स्वरूपण के रूप में, यह अनिवार्य रूप से वैकल्पिक, गैर-अनिवार्य उपाय है, किसी भी प्रकार की मानवीय त्रुटि के लिए प्रवण है।

मुझे लगता है कि यह सब एक बहुत पुरानी अंधविश्वास के कारण, OWASP या पीएचपी मैनुअल जैसे अधिकारियों द्वारा समर्थित है, जो एसक्यूएल इंजेक्शन से "बचने" और सुरक्षा के बीच समानता का प्रचार करता है।

उम्र के लिए PHP मैनुअल ने जो भी कहा, उसके बावजूद, *_escape_string किसी भी माध्यम से डेटा को सुरक्षित बनाता है और इसका इरादा कभी नहीं किया गया है। स्ट्रिंग के अलावा किसी भी एसक्यूएल भाग के लिए बेकार होने के अलावा, मैन्युअल एस्केपिंग गलत है, क्योंकि यह स्वचालित रूप से स्वचालित के विपरीत मैनुअल है।

और ओडब्ल्यूएएसपी इससे भी बदतर हो जाता है, उपयोगकर्ता इनपुट से बचने पर जोर देता है जो एक पूर्ण बकवास है: इंजेक्शन सुरक्षा के संदर्भ में ऐसा कोई शब्द नहीं होना चाहिए। प्रत्येक चर संभावित रूप से खतरनाक है - कोई फर्क नहीं पड़ता स्रोत! या, दूसरे शब्दों में - प्रत्येक चर को एक प्रश्न में डालने के लिए उचित रूप से स्वरूपित किया जाना चाहिए - स्रोत को फिर से कोई फर्क नहीं पड़ता। यह गंतव्य है जो मायने रखता है। जिस क्षण एक डेवलपर बकरियों को बकरियों से अलग करना शुरू कर देता है (सोच रहा है कि कुछ विशेष चर "सुरक्षित" है या नहीं) वह आपदा के प्रति अपना पहला कदम उठाता है। उल्लेख नहीं है कि यहां तक ​​कि शब्द भी प्रवेश बिंदु पर भारी भागने का सुझाव देता है, जैसा कि बहुत ही जादू उद्धरण सुविधा जैसा दिखता है - पहले ही तुच्छ, बहिष्कृत और हटा दिया गया है।

तो, जो भी "भागने" के विपरीत, तैयार बयान वह उपाय है जो वास्तव में एसक्यूएल इंजेक्शन (जब लागू हो) से बचाता है।

यदि आप अभी भी आश्वस्त नहीं हैं, तो मैंने एक कदम-दर-चरण स्पष्टीकरण लिखा है, द हिचहिकर गाइड टू एसक्यूएल इंजेक्शन रोकथाम , जहां मैंने इन सभी मामलों को विस्तार से समझाया और यहां तक ​​कि एक अनुभाग को पूरी तरह से खराब प्रथाओं और उनके प्रकटीकरण के लिए समर्पित किया।





mysql sql plsql