मेरे पास कोड का एक टुकड़ा है जो INSERT
विफल होने पर लेनदेन को वापस करने के लिए TRY / CATCH का उपयोग करता है। हालांकि, कोड के बीच में मेरे पास कोड का एक टुकड़ा है जो प्रति लूप राउंड में एक ईमेल भेजता है।
मेरी समस्या यह है कि लूप ईमेल भेजता है और फिर एक सम्मिलित करता है। तो मान लें कि 9 प्रक्रियाओं/राउंड के बाद, 10वां राउंड INSERT
में विफल हो जाता है; तो पूरा लेनदेन वापस ले लिया जाता है, लेकिन 9 ईमेल पहले ही भेजे जा चुके हैं। मैं इसे कैसे सुधार सकता हूं ताकि ईमेल पहले न भेजे जाएं? या लेन-देन विफल होने पर भेजे जाने वाले किसी भी ईमेल से कैसे बचें?
परीक्षण उद्देश्यों के लिए मेरे कोड का एक सरलीकृत संस्करण यहां दिया गया है।
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER PROCEDURE [dbo].[something]
AS
BEGIN
SET NOCOUNT, XACT_ABORT ON;
SET TRANSACTION ISOLATION LEVEL SERIALIZABLE
BEGIN TRY
DECLARE @something INT
DECLARE ROW_RES CURSOR FOR
SELECT something
FROM something
OPEN ROW_RES
FETCH NEXT FROM ROW_RES INTO @something
WHILE (@@fetch_status = 0)
BEGIN
IF (@something > 0)
BEGIN
EXEC msdb.dbo.sp_send_dbmail
@profile_name = 'myprofile',
@from_address = 'do_not_reply@me.com',
@recipients = 'me@me.com',
@copy_recipients = 'ccme@me.com',
@subject = @email_subject,
@body = @email_body,
@body_format = 'html'
END
FETCH NEXT FROM ROW_RES INTO @something
END
IF (@something = false )
BEGIN
UPDATE something
SET something = (@something)
WHERE something = @something
END
ELSE IF (@something = true)
BEGIN
INSERT INTO something (something)
VALUES (@something)
END
COMMIT TRAN
END TRY
BEGIN CATCH
DECLARE @MESSAGE NVARCHAR(2000), @SEVERITY INT, @STATE INT
--See if there is a hanging transaction
IF @@TRANCOUNT > 0 ROLLBACK TRAN
--Rethrow the error to the calling application
SET @MESSAGE = ERROR_MESSAGE()
SET @SEVERITY = ERROR_SEVERITY()
SET @STATE = ERROR_STATE()
RAISERROR(@MESSAGE, @SEVERITY, @STATE)
END CATCH
SET NOCOUNT OFF;
END
CLOSE ROW_RES
DEALLOCATE ROW_RES
2 जवाब
समस्या यह है कि लेन-देन शुरू करने के लिए आपके पास एक BEGIN TRAN
नहीं है। तो आपके बयान सभी एक संयुक्त लेनदेन के बजाय व्यक्तिगत ऑटो प्रतिबद्ध लेनदेन में चल रहे हैं।
यदि आप BEGIN TRAN
को try ब्लॉक की शुरुआत में जोड़ते हैं तो आपका मौजूदा कोड वांछित के रूप में काम करना चाहिए।
कर्सर के अंदर sp_send_dbmail
को कॉल करने के बजाय, आप इसके बजाय एक कतार तालिका में आवश्यक सभी मेटा डेटा सम्मिलित कर सकते हैं, और कर्सर पूरा होने के बाद, यदि कोई समस्या नहीं थी, तो आप एक और कर्सर या लूप चला सकते हैं जो बस भेजता है कतार तालिका में प्रत्येक पंक्ति के लिए ईमेल।
संबंधित सवाल
नए सवाल
sql-server
Microsoft SQL सर्वर एक रिलेशनल डेटाबेस मैनेजमेंट सिस्टम (RDBMS) है। कॉम्पैक्ट, एक्सप्रेस, एज़्योर, फास्ट-ट्रैक, एपीएस (पूर्व में पीडीडब्ल्यू) और एज़्योर SQL डीडब्ल्यू सहित सभी SQL सर्वर संस्करणों के लिए इस टैग का उपयोग करें। अन्य प्रकार के DBMS (MySQL, PostgreSQL, Oracle, आदि) के लिए इस टैग का उपयोग न करें। सॉफ़्टवेयर और मोबाइल विकास के मुद्दों के लिए इस टैग का उपयोग न करें, जब तक कि यह सीधे डेटाबेस से संबंधित न हो।