क्या परीक्षण करने का एक तरीका है कि क्या कमी के कारण DELETE विफल होगा?


10

मैं यह अनुमान लगाने में सक्षम होना चाहता हूं कि क्या कोई DELETE वास्तव में डिलीट किए बिना एक बाधा उल्लंघन में चलेगा।

ऐसा करने के लिए मेरे पास क्या विकल्प हैं? क्या DELETE का "ड्राई रन" करने का एक सरल तरीका है?


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

3
क्या आप देख सकते हैं कि क्या FK मौजूद है, और मानों को जाँचने के लिए SELECT स्टेटमेंट चलाते हैं?
SQLRockstar

हारून: हमें अलग-अलग लेनदेन में कई DELETEs का एक बैच चलाने की आवश्यकता है। यदि कोई विफल हो जाता है, तो दूसरे पहले से ही प्रतिबद्ध हैं। (शुरुआत से खराब डिजाइन, मुझे पता है, लेकिन यह मेरा आवेदन नहीं है, और यह नहीं बदल रहा है।) इस समय सबसे अच्छा समाधान यह देखने के लिए सूखा जांच करने की तरह लगता है कि क्या DELETEs विफल हो जाएगा।
जय सुलिवन

फिर भी यकीन नहीं होता कि मैं समझ गया हूं। क्या आप बाकी डिलीट को सफल होने देने की कोशिश कर रहे हैं, या आप सामने वाले की जाँच करने की कोशिश कर रहे हैं कि सभी डिलीट सफल होंगे, या उनमें से कोई भी नहीं होना चाहिए?
हारून बर्ट्रेंड

हारून: क्षमा करें, मैंने इसे स्पष्ट नहीं किया, लेकिन हाँ, मैं यह सुनिश्चित करने की कोशिश कर रहा हूँ कि वे सभी सफल हों, या उनमें से कोई भी सफल न हो।
जय सुलिवन

जवाबों:


24

यदि आपका लक्ष्य सभी को हटाने की प्रक्रिया करना है, यदि वे सभी सफल होते हैं, तो केवल TRY / CATCH का उपयोग क्यों न करें:

BEGIN TRANSACTION;
BEGIN TRY
  DELETE #1;
  DELETE #2;
  DELETE #3;
  COMMIT TRANSACTION;
END TRY
BEGIN CATCH
  ROLLBACK TRANSACTION;
END CATCH

यदि लक्ष्य सभी सफल डिलीट को सफल होने की अनुमति देना है, भले ही एक या अधिक असफल हो, तो आप व्यक्तिगत TRY / CATCH का उपयोग कर सकते हैं, उदाहरण के लिए

BEGIN TRY
  DELETE #1;
END TRY
BEGIN CATCH
  PRINT 1;
END CATCH

BEGIN TRY
  DELETE #2;
END TRY
BEGIN CATCH
  PRINT 1;
END CATCH

6

एक विकल्प यह है कि एक लेन-देन शुरू करें, अपना डिलीट करें, और फिर हमेशा रोलबैक करें:

begin tran

delete Table1 where col1 = 1

-- Test whether it is there
select * from Table1 where col1 = 1

rollback tran

-- Confirm that it is still there
select * from Table1 where col1 = 1

1
और अगर डिलीट सफल हो जाता है, तो इसे फिर से चलाएं? यदि डिलीट बहुत महंगा है तो क्या होगा? और अगर डिलीट फेल होता है, तो क्या? आपने एक हटा दिया है और दो चयन किए हैं। मैं अगले डिलीट पर जाने का फैसला कैसे करूं या नहीं?
हारून बर्ट्रेंड

1
यदि वे आवश्यकताओं का हिस्सा हैं, तो उन्हें संभाला जाना चाहिए। यह उत्तर एक "साधारण 'ड्राई रन' के संबंध में है।"
GaTechThomas

वैसे वे तब नहीं थे जब आपने पहली बार अपना जवाब प्रस्तुत किया था, लेकिन अब उन्हें स्पष्ट कर दिया गया है।
हारून बर्ट्रेंड

4
@GaTechThomas हारून बहुत योगदान देता है, इसलिए वह कभी-कभी संक्षिप्त होता है, लेकिन मुझे यकीन है कि उसका इरादा आक्रामक नहीं था। मैंने द हीप में इस पर चर्चा की और मैं आपके साथ भी ऐसा करने के मौके के लिए आभारी रहूंगा।
जैक का कहना है कि topanswers.xyz

1
@JackDouglas मैंने The Heap टिप्पणियों को पढ़ा है जो आप संदर्भ और बिंदु को समझते हैं। सामुदायिक टिप्पणी उस हिस्से को छोड़कर उचित थी जहां मुझे उसकी आक्रामकता की ओर इशारा करने के लिए मसख़रा कहा जाता था। मुझे समझ नहीं आता कि मैं वह कैसे हूं जिसे आक्रामक के रूप में देखा गया था। मैंने प्रश्न का एक वैध उत्तर पोस्ट किया क्योंकि यह उस समय खिंच गया था। यह उत्पादन की गुणवत्ता के लिए नहीं पूछता था - कभी-कभी आपको बस त्वरित और आसान की आवश्यकता होती है। तो मेरे जवाब पर मुझे इंगित प्रश्न मिलते हैं। उपस्थिति यह थी कि वह मेरे उत्तर को अस्वीकार कर रहा था ताकि उसे चुना जाए। क्या हमें यह धागा कहीं और ले जाना चाहिए?
GaTechThomas 16

0

मैं कुछ कोड के साथ आरोन बर्ट्रेंड द्वारा प्रदान किए गए समाधान को बेहतर बनाना चाहूंगा, यदि आप किसी तालिका के किसी भी तत्व को जोड़ने की कोशिश करना चाहते हैं, तो अपवादों को अनदेखा करने या असफल होने की प्रक्रिया को रोकने के लिए अपवादों को प्रबंधित करना।

यह तालिका से रिकॉर्ड का चयन करेगा और फिर उन्हें अपवाद के बिना हटाने की कोशिश करेगा:

DECLARE @MaxErrors INT
SET @MaxErrors = 5;    // Setting 0 will stop process after the first error!

SELECT
    [Id]
    , ROW_NUMBER() OVER (ORDER BY Id ASC) AS [Index]
INTO #DeletingItems
FROM myTable

DECLARE @Current INT, @Max INT, @Id INT, @TotErrors INT
SELECT
    @Current = 1
    , @TotErrors = 0
    , @Max = MAX([Index])
FROM #DeletingTable

WHILE @Current <= @Max
BEGIN
    SELECT
        @Id = [Id]
    FROM #DeletingItems
    WHERE
        [Index] = @Index;

    BEGIN TRANSACTION;    
    BEGIN TRY    
        DELETE FROM myTable WHERE [Id] = @Id;

        COMMIT TRANSACTION;    
    END TRY    
    BEGIN CATCH    
        ROLLBACK TRANSACTION;

        SET @TotErrors = @TotErrors + 1;

        IF @TotErrors > @MaxErrors
            BREAK;
    END CATCH

    SET @Current = @Current + 1;
END

1
क्यों? यह स्वीकार किए गए उत्तर पर एक सुधार कैसे है?
टूलमेकरसेव जुले
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.