एकल SQL कथन में समाधान। PostgreSQL की आवश्यकता है 8.4 या बाद में हालांकि।
निम्न डेमो पर विचार करें:
परीक्षण सेटअप:
CREATE TEMP TABLE tbl (
id serial PRIMARY KEY
,txt text UNIQUE -- obviously there is unique column (or set of columns)
);
INSERT INTO tbl(txt) VALUES ('one'), ('two');
INSERT / सेलेक्ट कमांड:
WITH v AS (SELECT 'three'::text AS txt)
,s AS (SELECT id FROM tbl JOIN v USING (txt))
,i AS (
INSERT INTO tbl (txt)
SELECT txt
FROM v
WHERE NOT EXISTS (SELECT * FROM s)
RETURNING id
)
SELECT id, 'i'::text AS src FROM i
UNION ALL
SELECT id, 's' FROM s;
-
पहला CTE v सख्ती से जरूरी नहीं है, लेकिन यह हासिल करता है कि आपको अपने मानों . को दर्ज करना होगा केवल एक बार।
-
दूसरा CTE s चयन करता है
id
tbl
. से अगर "पंक्ति" मौजूद है। -
तीसरा CTE मैं सम्मिलित करता हूं "पंक्ति" को
tbl
. में अगर (और केवल अगर) यह मौजूद नहीं है, तोid
returning । -
अंतिम
SELECT
id
लौटाता है . मैंने एक कॉलम जोड़ा हैsrc
"स्रोत" का संकेत - क्या "पंक्ति" पहले से मौजूद है औरid
एक चयन से आता है, या "पंक्ति" नई थी और इसलिएid
. है । -
यह संस्करण यथासंभव तेज़ होना चाहिए क्योंकि इसके लिए
tbl
. से अतिरिक्त चयन की आवश्यकता नहीं है और इसके बजाय सीटीई का उपयोग करता है।
बहु-उपयोगकर्ता वातावरण में संभावित दौड़ स्थितियों के विरुद्ध इसे सुरक्षित बनाने के लिए:
पोस्टग्रेज़ में नई यूपीएसईआरटी का उपयोग करने वाली अद्यतन तकनीकों के लिए भी 9.5 या बाद में:
- क्या किसी ऐसे फ़ंक्शन में SELECT या INSERT है जो दौड़ की स्थिति से ग्रस्त है?