2012-08-09 14 views
31

मैं पीएल/पीजीएसक्यूएल में एक फ़ंक्शन लिख रहा हूं, और मैं यह जांचने का सबसे आसान तरीका ढूंढ रहा हूं कि कोई पंक्ति मौजूद है या नहीं।
अभी मैं integer को boolean में चुन रहा हूं, जो वास्तव में काम नहीं करता है। मुझे पीएल/पीजीएसक्यूएल के साथ पर्याप्त अनुभव नहीं हुआ है, यह अभी तक करने का सबसे अच्छा तरीका है।पीएल/पीजीएसक्यूएल जांच अगर कोई पंक्ति मौजूद है

यहाँ मेरी समारोह का हिस्सा है:

DECLARE person_exists boolean; 
BEGIN 

person_exists := FALSE; 

SELECT "person_id" INTO person_exists 
    FROM "people" p 
WHERE p.person_id = my_person_id 
LIMIT 1; 

IF person_exists THEN 
    -- Do something 
END IF; 

END; $$ LANGUAGE plpgsql; 

अद्यतन - मैं अब के लिए कुछ इस तरह कर रहा हूँ:

DECLARE person_exists integer; 
BEGIN 

person_exists := 0; 

SELECT count("person_id") INTO person_exists 
    FROM "people" p 
WHERE p.person_id = my_person_id 
LIMIT 1; 

IF person_exists < 1 THEN 
    -- Do something 
END IF; 

उत्तर

90

सरल, छोटा, तेज:EXISTS

IF EXISTS (SELECT 1 FROM people WHERE person_id = my_person_id) THEN 
    -- do something 
END IF; 

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

नीचे दी गई टिप्पणियों में @a_horse_with_no_name से इनपुट के साथ बेहतर हुआ।

+0

अच्छा बिंदु! (हालांकि person_id शायद प्राथमिक कुंजी है, इसलिए यह इंडेक्स लुकअप का उपयोग करके केवल एक ही तालिका को "स्कैन" करेगा)। –

+0

@a_horse_with_no_name: अभी तक (पोस्टग्रेज़ 9.1) 'गिनती()' * हमेशा * अनुक्रमिक स्कैन ट्रिगर करता है। 'किसी भी तालिका के साथ tbl' से एक्सप्लान विश्लेषण चयन गिनती (आईडी) का प्रयास करें। पोस्टग्रेस विकी में धीमी गिनती पर अधिक (http://wiki.postgresql.org/wiki/Slow_Counting)। पोस्टग्रेस 9.2 का नया इंडेक्स-स्कैन स्कैन चीजों को बेहतर बनाने के लिए माना जाता है, क्योंकि यह (गिनती (आईडी) 'के लिए इंडेक्स स्कैन का उपयोग कर सकता है (हालांकि कुछ स्थितियां) - अभी तक कोशिश करने और इसे अपने लिए देखने के लिए नहीं है, हालांकि .. –

+3

ए 'गिनती (*)' * एक शर्त के साथ * (विशेष रूप से पीके कॉलम पर नहीं) ** ** अनुक्रमिक स्कैन ट्रिगर नहीं करेगा **। –

2

उपयोग गिनती (*)

declare 
    cnt integer; 
begin 
    SELECT count(*) INTO cnt 
    FROM people 
    WHERE person_id = my_person_id; 

IF cnt > 0 THEN 
    -- Do something 
END IF; 

संपादित करें (डाउनवॉटर के लिए जिन्होंने बयान और अन्य कुछ ऐसा नहीं किया जो शायद कुछ भी कर रहे हों)

समाधान केवल प्रभावी है क्योंकि कॉलम पर एक क्लॉज है (और कॉलम का नाम बताता है कि इसकी प्राथमिक कुंजी - तो जहां खंड अत्यधिक प्रभावी है)

उस where खंड के कारण किसी प्राथमिकता द्वारा पहचाने जाने वाली पंक्ति की उपस्थिति का परीक्षण करने के लिए LIMIT या कुछ और उपयोग करने की आवश्यकता नहीं है। यह इसका परीक्षण करने का एक प्रभावी तरीका है।

+0

हाहा मैंने आपके पोस्ट को इस पोस्ट को सही तरीके से जोड़ा क्योंकि आपने इसे पोस्ट किया था। – nnyby

+2

इस उद्देश्य के लिए COUNT का उपयोग न करें - यह प्रदर्शन समस्या है - या आपको व्युत्पन्न तालिका का चयन करना होगा (*) से चुनें (चुनें * लोगों से LIMIT 1) x –

+1

@PavelStehule: यहां तक ​​कि जब 'कहां' स्थिति है ** प्राथमिक कुंजी **? मैं कल्पना नहीं कर सकता कि यह आपके कथन से कितना धीमा होगा। निष्पादन योजना दोनों समाधानों के लिए लगभग समान है। –

संबंधित मुद्दे