एकल क्वेरी का उपयोग करके कैसे डालें या अपडेट करें?


26

मेरे पास एक टेबल टेस्ट है जिसमें कॉलम आईडी है जो प्राथमिक कुंजी और ऑटो इंक्रीमेंट और नाम है। मैं एक नया रिकॉर्ड डालना चाहता हूं अगर कोई रिकॉर्ड न हो तो ही और। उदाहरण के लिए

इनपुट आईडी = 30122 और नाम = जॉन है

अगर आईडी 30122 के साथ रिकॉर्ड हैं तो मेरे पास नाम कॉलम को जॉन में अपडेट करना है, अगर कोई रिकॉर्ड नहीं है तो मैंने एक नया रिकॉर्ड डाला है।

मैं जैसे 2 प्रश्नों का उपयोग कर सकता हूँ

select * from test where id=30122

अगर इसके कुछ रिकॉर्ड हैं तो मैं उपयोग कर सकता हूं update test set name='john' where id=3012

या अगर यह रिकॉर्ड नहीं है तो मैं उपयोग कर सकता हूं

insert into test(name) values('john')

लेकिन मैं सिंगल क्वेरी का उपयोग करना चाहता था?

क्या कोई बता सकता है कि क्या यह संभव है?


1
But I wanted to use single query?क्यूं कर?
हारून बर्ट्रेंड

@AaronBertrand मेरा बैक एंड java.So का उपयोग करके विकसित किया गया है। यदि मैं 2 बार उपयोग करता हूं तो मुझे DB 2 बार हिट करना होगा। यदि यह एक क्वेरी का उपयोग करके किया जा सकता है, तो 2 प्रश्नों का उपयोग क्यों किया जाए
SpringLearner

1
जावा एक संग्रहीत प्रक्रिया का समर्थन नहीं करता है, या दो बयानों के साथ एक एकल बैच डेटाबेस में केवल एक हिट की आवश्यकता है?
हारून बर्ट्रेंड

@AaronBertrand क्या आप इसका उदाहरण दे सकते हैं कि आप sql सर्वर 2008 या बाद में इसे कैसे संभालेंगे?
eaglei22

1
@ eaglei22 मैं नीचे vijayp के उत्तर में 2 उदाहरण का उपयोग करेगा। मैं अभी भी MERGEकिसी भी संस्करण में, यहां तक ​​कि SQL सर्वर 2019 का चयन नहीं करूंगा । उस पर कुछ पृष्ठभूमि
हारून बर्ट्रेंड

जवाबों:


41

आप यह कोशिश कर सकते हैं

IF EXISTS(select * from test where id=30122)
   update test set name='john' where id=3012
ELSE
   insert into test(name) values('john');

बेहतर प्रदर्शन के लिए अन्य दृष्टिकोण है

update test set name='john' where id=3012
IF @@ROWCOUNT=0
   insert into test(name) values('john');

और स्कीमा उपसर्ग पर किक करने के लिए इस बुरी आदतों को भी पढ़ें


4
पहला उदाहरण बेकार है और अक्सर गतिरोध पैदा कर सकता है - मैं इसे बिल्कुल नहीं सुझाऊंगा।
हारून बर्ट्रेंड

@AaronBertrand विस्तृत करने के लिए देखभाल? धन्यवाद
Hexo

5
@SlapY ज़रूर, पहले उदाहरण में, आप कह रहे हैं: "अरे, SQL सर्वर, क्या इस आईडी के साथ कोई पंक्ति है?" SQL सर्वर पंक्ति को खोजने के लिए बंद हो जाता है, शायद एक स्कैन का उपयोग करके, और फिर उत्तर के साथ वापस आता है। "क्यों, हाँ, उपयोगकर्ता, मेरे पास उस आईडी के साथ एक पंक्ति है!" फिर आप कहते हैं, "ठीक है, SQL सर्वर, उस पंक्ति को फिर से ढूंढें , लेकिन इस बार, इसे अपडेट करें!" क्या आप देखते हैं कि दो बार तलाश या स्कैन करना कितना बेकार है? क्या आप सोच सकते हैं कि यदि कोई अन्य उपयोगकर्ता SQL सर्वर से पंक्ति के अस्तित्व के बारे में एक ही सवाल पूछता है, तो इससे पहले कि आप इसके बारे में कुछ करने के लिए आगे बढ़ें?
हारून बर्ट्रेंड

धन्यवाद, मैं अभी यह नहीं देख रहा हूं कि पहला क्यों दूसरा गतिरोध के लिए गतिरोध की धमकी दे रहा है? दोनों में कई स्टेटमेंट्स होते हैं, जिन्हें अगर पूरे लॉक के साथ नहीं चलाया जाए तो इंटरसेप्ट किया जा सकता है। क्या मै गलत हु?
हेक्सो

2
@ 0x25b3 ऐसा नहीं है कि किसी को गतिरोध का खतरा है और दूसरे को नहीं है, ऐसा नहीं है कि पहला उदाहरण उनके लिए बहुत अधिक है। आपको किसी भी मामले में पूर्ण और उचित लेनदेन में लपेटना चाहिए, लेकिन लोग ऐसा नहीं करते ...
हारून बर्ट्रेंड

17

SQL सर्वर 2008 या बाद में, आप उपयोग कर सकते हैं MERGE:

तालिका

CREATE TABLE dbo.Test
(
    id integer NOT NULL,
    name varchar(30) NULL,

    CONSTRAINT PK_dbo_Test__id
        PRIMARY KEY CLUSTERED (id)
);

सवाल

MERGE dbo.Test WITH (SERIALIZABLE) AS T
USING (VALUES (3012, 'john')) AS U (id, name)
    ON U.id = T.id
WHEN MATCHED THEN 
    UPDATE SET T.name = U.name
WHEN NOT MATCHED THEN
    INSERT (id, name) 
    VALUES (U.id, U.name);

SERIALIZABLEसंकेत के लिए आवश्यक है उच्च संगामिति के तहत सही संचालन

आप माइकल जे। स्वार्ट द्वारा सामान्य तरीकों की तुलना पा सकते हैं:

Mythbusting: समवर्ती अद्यतन / समाधान डालें


8
मर्ज़ के कुछ मुद्दे हैं
vonPryz

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