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

ट्रिगर त्रुटि:वर्तमान लेनदेन प्रतिबद्ध नहीं किया जा सकता है और लॉग फ़ाइल में लिखने वाले संचालन का समर्थन नहीं कर सकता है

यह त्रुटि तब होती है जब आप किसी लेन-देन के अंदर एक कोशिश/पकड़ ब्लॉक का उपयोग करते हैं। आइए एक छोटे से उदाहरण पर विचार करें:

SET XACT_ABORT ON

IF object_id('tempdb..#t') IS NOT NULL
    DROP TABLE #t
CREATE TABLE #t (i INT NOT NULL PRIMARY KEY)

BEGIN TRAN
    INSERT INTO #t (i) VALUES (1)
    INSERT INTO #t (i) VALUES (2)
    INSERT INTO #t (i) VALUES (3)
    INSERT INTO #t (i) VALUES (1) -- dup key error, XACT_ABORT kills the batch
    INSERT INTO #t (i) VALUES (4) 

COMMIT  TRAN
SELECT * FROM #t

जब चौथा इंसर्ट एक त्रुटि का कारण बनता है, तो बैच समाप्त हो जाता है और लेनदेन वापस आ जाता है। अब तक कोई आश्चर्य नहीं।

आइए अब उस त्रुटि को TRY/CATCH ब्लॉक के साथ संभालने का प्रयास करें:

SET XACT_ABORT ON
IF object_id('tempdb..#t') IS NOT NULL
    DROP TABLE #t
CREATE TABLE #t (i INT NOT NULL PRIMARY KEY)

BEGIN TRAN
    INSERT INTO #t (i) VALUES (1)
    INSERT INTO #t (i) VALUES (2)
    BEGIN TRY
        INSERT INTO #t (i) VALUES (3)
        INSERT INTO #t (i) VALUES (1) -- dup key error
    END TRY
    BEGIN CATCH
        SELECT ERROR_MESSAGE()
    END CATCH  
    INSERT INTO #t (i) VALUES (4)
    /* Error the Current Transaction cannot be committed and 
    cannot support operations that write to the log file. Roll back the transaction. */

COMMIT TRAN
SELECT * FROM #t

हमने डुप्लिकेट कुंजी त्रुटि पकड़ी, लेकिन अन्यथा, हम बेहतर नहीं हैं। हमारा बैच अभी भी समाप्त हो गया है, और हमारा लेनदेन अभी भी वापस आ गया है। कारण वास्तव में बहुत आसान है:

TRY/CATCH ब्लॉक लेन-देन को प्रभावित नहीं करते हैं।

XACT_ABORT ON होने के कारण, जिस क्षण डुप्लीकेट कुंजी त्रुटि होती है, लेन-देन बर्बाद हो जाता है। के लिए किया गया है। यह घातक रूप से घायल हो गया है। यह दिल के माध्यम से गोली मार दी गई है ... और त्रुटि को दोष देना है। TRY/CATCH SQL सर्वर देता है ... एक बुरा नाम। (क्षमा करें, विरोध नहीं कर सका)

दूसरे शब्दों में, यह कभी नहीं . होगा प्रतिबद्ध हैं और करेंगे हमेशा वापस लुढ़क जाना। एक TRY/CATCH ब्लॉक लाश को गिराने के लिए केवल इतना ही कर सकता है। हम XACT_STATE () . का उपयोग कर सकते हैं यह देखने के लिए कार्य करता है कि क्या हमारा लेनदेन प्रतिबद्ध है। यदि ऐसा नहीं है, तो लेनदेन को वापस लेने का एकमात्र विकल्प है।

SET XACT_ABORT ON -- Try with it OFF as well.
IF object_id('tempdb..#t') IS NOT NULL
    DROP TABLE #t
CREATE TABLE #t (i INT NOT NULL PRIMARY KEY)

BEGIN TRAN
    INSERT INTO #t (i) VALUES (1)
    INSERT INTO #t (i) VALUES (2)

    SAVE TRANSACTION Save1
    BEGIN TRY
        INSERT INTO #t (i) VALUES (3)
        INSERT INTO #t (i) VALUES (1) -- dup key error
    END TRY
    BEGIN CATCH
        SELECT ERROR_MESSAGE()
        IF XACT_STATE() = -1 -- Transaction is doomed, Rollback everything.
            ROLLBACK TRAN
        IF XACT_STATE() = 1 --Transaction is commitable, we can rollback to a save point
            ROLLBACK TRAN Save1
    END CATCH  
    INSERT INTO #t (i) VALUES (4)

IF @@TRANCOUNT > 0
    COMMIT TRAN
SELECT * FROM #t

ट्रिगर हमेशा लेन-देन के संदर्भ में निष्पादित होते हैं, इसलिए यदि आप उनके अंदर TRY/CATCH का उपयोग करने से बच सकते हैं, तो चीजें बहुत आसान होती हैं।

आपकी समस्या के समाधान के लिए, एक CLR Stored Proc डायनेमिक SQL को निष्पादित करने के लिए एक अलग कनेक्शन में SQL सर्वर से वापस कनेक्ट हो सकता है। आप एक नए लेन-देन में कोड को निष्पादित करने की क्षमता हासिल करते हैं और त्रुटि प्रबंधन तर्क को लिखना आसान है और C# में समझना आसान है।




  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. SQL सर्वर में EXISTS लॉजिकल ऑपरेटर का उपयोग कैसे करें - SQL सर्वर / TSQL ट्यूटोरियल पार्ट 125

  2. DECRYPTBYASYMKEY () अपेक्षित मूल्य नहीं लौटा रहा है

  3. 4 प्रमुख डेटाबेस निगरानी गतिविधियां प्रत्येक डीबीए को पता होनी चाहिए

  4. उदाहरण के साथ SQL जॉइन प्रकारों का अवलोकन

  5. दो डेटाबेस के बीच विदेशी कुंजी संबंध जोड़ें