बहुत से लोग आपको उपयोग करने का सुझाव देंगे MERGE
, लेकिन मैं आपको इसके प्रति सावधान करता हूं। डिफ़ॉल्ट रूप से, यह आपको कई बयानों की तुलना में संगति और दौड़ की स्थिति से बचाता नहीं है, लेकिन यह अन्य खतरों का परिचय देता है:
http://www.mssqltips.com/sqlservertip/3074/use-caution-with-sql-servers-merge-statement/
यहां तक कि इस "सरल" सिंटैक्स उपलब्ध होने के बावजूद, मैं अभी भी इस दृष्टिकोण (त्रुटि से निपटने के लिए छोड़ी गई त्रुटि) को पसंद करता हूं:
SET TRANSACTION ISOLATION LEVEL SERIALIZABLE;
BEGIN TRANSACTION;
UPDATE dbo.table SET ... WHERE PK = @PK;
IF @@ROWCOUNT = 0
BEGIN
INSERT dbo.table(PK, ...) SELECT @PK, ...;
END
COMMIT TRANSACTION;
बहुत सारे लोग इस तरह से सुझाव देंगे:
SET TRANSACTION ISOLATION LEVEL SERIALIZABLE;
BEGIN TRANSACTION;
IF EXISTS (SELECT 1 FROM dbo.table WHERE PK = @PK)
BEGIN
UPDATE ...
END
ELSE
INSERT ...
END
COMMIT TRANSACTION;
लेकिन यह सब उपलब्धियां सुनिश्चित कर रही है कि अद्यतन किए जाने वाली पंक्ति का पता लगाने के लिए आपको तालिका को दो बार पढ़ने की आवश्यकता हो सकती है। पहले नमूने में, आपको केवल एक बार पंक्ति का पता लगाने की आवश्यकता होगी। (दोनों मामलों में, यदि प्रारंभिक रीड से कोई पंक्तियाँ नहीं मिली हैं, तो एक प्रविष्टि होती है।)
अन्य इस तरह से सुझाव देंगे:
BEGIN TRY
INSERT ...
END TRY
BEGIN CATCH
IF ERROR_NUMBER() = 2627
UPDATE ...
END CATCH
हालाँकि, यह समस्याग्रस्त है अगर SQL सर्वर को अपवादों को छोड़ देने के अलावा और कोई कारण नहीं है जो आप पहली बार में रोक सकते थे, वह अधिक महंगा है, दुर्लभ परिदृश्य को छोड़कर जहां लगभग हर इंसर्ट विफल रहता है। मैं यहाँ जितना साबित करता हूँ: