Sqlserver
 sql >> डेटाबेस >  >> RDS >> Sqlserver

एक सशर्त अप्सर्ट संग्रहीत प्रक्रिया को कैसे कार्यान्वित करें?

मैंने पिछले वर्षों में इस्तेमाल की गई इस चाल को प्रमाणित करने के लिए निम्नलिखित स्क्रिप्ट को एक साथ थप्पड़ मारा। यदि आप इसका उपयोग करते हैं, तो आपको अपने उद्देश्यों के अनुरूप इसे संशोधित करने की आवश्यकता होगी। टिप्पणियों का पालन करें:

/*
CREATE TABLE Item
 (
   Title      varchar(255)  not null
  ,Teaser     varchar(255)  not null
  ,ContentId  varchar(30)  not null
  ,RowLocked  bit  not null
)


UPDATE item
 set RowLocked = 1
 where ContentId = 'Test01'

*/


DECLARE
  @Check varchar(30)
 ,@pContentID varchar(30)
 ,@pTitle varchar(255)
 ,@pTeaser varchar(255)

set @pContentID = 'Test01'
set @pTitle     = 'TestingTitle'
set @pTeaser    = 'TestingTeasier'

set @check = null

UPDATE dbo.Item
 set
   @Check = ContentId
  ,Title  = @pTitle
  ,Teaser = @pTeaser
 where ContentID = @pContentID
  and RowLocked = 0

print isnull(@check, '<check is null>')

IF @Check is null
    INSERT dbo.Item (ContentID, Title, Teaser, RowLocked)
     values (@pContentID, @pTitle, @pTeaser, 0)

select * from Item

यहां ट्रिक यह है कि आप अपडेट स्टेटमेंट के भीतर स्थानीय चर में मान सेट कर सकते हैं। ऊपर, "ध्वज" मान केवल तभी सेट हो जाता है जब अद्यतन कार्य करता है (अर्थात, अद्यतन मानदंड पूरे होते हैं); अन्यथा, यह परिवर्तित नहीं होगा (यहाँ, शून्य पर छोड़ दिया गया है), आप उसके लिए जाँच कर सकते हैं, और उसके अनुसार प्रक्रिया कर सकते हैं।

लेन-देन के लिए और इसे क्रमबद्ध बनाने के लिए, आगे बढ़ने का सुझाव देने से पहले मैं इस बारे में और जानना चाहता हूं कि लेनदेन के भीतर क्या समझाया जाना चाहिए।

- परिशिष्ट, नीचे दूसरी टिप्पणी से अनुवर्ती -----------

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

मैंने कुछ और परीक्षण किया (कॉलम ContentId पर प्राथमिक कुंजी बाधा जोड़ा, अद्यतन और INSERT को लेनदेन में लपेटें, अद्यतन में क्रमिक संकेत जोड़ें) और हां, जो कुछ भी आप चाहते हैं उसे करना चाहिए। असफल अपडेट इंडेक्स के उस हिस्से पर एक रेंज लॉक को थप्पड़ मार देता है, और यह कॉलम में उस नए मान को सम्मिलित करने के किसी भी एक साथ प्रयास को अवरुद्ध कर देगा। बेशक, अगर एन अनुरोध एक साथ सबमिट किए जाते हैं, तो "पहला" पंक्ति बनाएगा, और इसे तुरंत दूसरे, तीसरे, आदि द्वारा अपडेट किया जाएगा - जब तक कि आप लाइन के साथ कहीं भी "लॉक" सेट नहीं करते। अच्छी चाल!

(ध्यान दें कि कुंजी कॉलम पर इंडेक्स के बिना, आप पूरी तालिका को लॉक कर देंगे। साथ ही, रेंज लॉक नए मान के "दोनों तरफ" पंक्तियों को लॉक कर सकता है - या शायद वे नहीं करेंगे, मैंने नहीं किया उसका परीक्षण करें। कोई बात नहीं, क्योंकि ऑपरेशन की अवधि [?] एकल-अंक मिलीसेकंड में होनी चाहिए।)



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. CTE से तालिका में रिकॉर्ड अपडेट करें

  2. एमएस एक्सेस त्रुटि ओडीबीसी - कॉल विफल। कास्ट विनिर्देश के लिए अमान्य वर्ण मान (#0)

  3. फ़िल्टरिंग जॉइन:WHERE बनाम ON

  4. SQL सर्वर 2005 जॉब CmdExec टाइमआउट कैसे सेट करें?

  5. विषम प्रश्नों के लिए कनेक्शन के लिए ANSI_NULLS और ANSI_WARNINGS विकल्पों को सेट करने की आवश्यकता होती है। यह सुसंगत क्वेरी शब्दार्थ सुनिश्चित करता है