সঞ্চিত পদ্ধতিতে লেনদেন


12

আমার একক লেনদেনের জন্য একটি আপডেট ও ইনসার্ট করা দরকার। এই কোডটি নিজের মতো করে ঠিকঠাক কাজ করে তবে আমি এটি সহজে কল করতে এবং প্রয়োজনীয় পরামিতিগুলিতে পাস করতে চাই। আমি যখন কোনও সঞ্চিত পদ্ধতিতে এই লেনদেনকে বাসা বেঁধে দেওয়ার চেষ্টা করি তখন আমি প্রচুর সিনট্যাক্স ত্রুটিতে চলে যাই।

নীচের কোডটি কীভাবে সহজেই কল করা যায় তাই আমি কীভাবে আবদ্ধ করতে পারি?

BEGIN TRANSACTION AssignUserToTicket
GO

DECLARE @updateAuthor varchar(100)
DECLARE @assignedUser varchar(100)
DECLARE @ticketID bigint

SET @updateAuthor = 'user1'
SET @assignedUser = 'user2'
SET @ticketID = 123456

    UPDATE tblTicket SET ticketAssignedUserSamAccountName = @assignedUser WHERE (ticketID = @ticketID);
    INSERT INTO [dbo].[tblTicketUpdate]
           ([ticketID]
           ,[updateDetail]
           ,[updateDateTime]
           ,[userSamAccountName]
           ,[activity])
     VALUES
           (@ticketID,
           'Assigned ticket to ' + @assignedUser,
           GetDate(),
           @updateAuthor,
           'Assign');
GO
COMMIT TRANSACTION AssignUserToTicket

1
সম্ভবত "ত্রুটিগুলি" কী ( আপনার প্রশ্নের নীচে সম্পাদনা লিঙ্কটি ব্যবহার করুন ) সম্পর্কে আপনার প্রশ্নে বিশদ যুক্ত করলে এটি সম্ভবত সহায়তা করবে । এছাড়াও, দয়া করে এই সফর গ্রহণ করুন । ধন্যবাদ!
ম্যাক্স ভার্নন

উত্তর:


15

আপনার সেই কোডটি CREATE PROCEDURE ...সিনট্যাক্সে মোড়ানো দরকার এবং GOবিবৃতিগুলি পরে BEGIN TRANSACTIONএবং আগে সরিয়ে ফেলতে হবে COMMIT TRANSACTION

GO
CREATE PROCEDURE dbo.AssignUserToTicket
(
     @updateAuthor varchar(100)
    , @assignedUser varchar(100)
    , @ticketID bigint
)
AS
BEGIN
    BEGIN TRANSACTION;
    SAVE TRANSACTION MySavePoint;
    SET @updateAuthor = 'user1';
    SET @assignedUser = 'user2';
    SET @ticketID = 123456;

    BEGIN TRY
        UPDATE dbo.tblTicket 
        SET ticketAssignedUserSamAccountName = @assignedUser 
        WHERE (ticketID = @ticketID);

        INSERT INTO [dbo].[tblTicketUpdate]
            (
            [ticketID]
            ,[updateDetail]
            ,[updateDateTime]
            ,[userSamAccountName]
            ,[activity]
            )
        VALUES (
            @ticketID
            , 'Assigned ticket to ' + @assignedUser
            , GetDate()
            , @updateAuthor
            , 'Assign'
            );
        COMMIT TRANSACTION 
    END TRY
    BEGIN CATCH
        IF @@TRANCOUNT > 0
        BEGIN
            ROLLBACK TRANSACTION MySavePoint; -- rollback to MySavePoint
        END
    END CATCH
END;
GO

এছাড়াও মনে রাখবেন, কিছু ত্রুটি দেখা TRY...CATCHদিলে আমি একটি বিবৃতি সম্পাদনের অনুমতি দিতে একটি বিবৃতি ব্লক যুক্ত করেছি ROLLBACK TRANSACTION। এর চেয়ে আপনার সম্ভবত আরও ভাল ত্রুটি পরিচালনা করা দরকার তবে আপনার প্রয়োজনীয়তা সম্পর্কে অজান্তে এটি সর্বোত্তম difficult

কিছু ভাল পড়া:

  1. সর্বদা স্কিমা নির্দিষ্ট করুন

  2. সঞ্চিত পদ্ধতি সেরা অভ্যাস

  3. খারাপ অভ্যাস এড়াতে


1
আপনি এখনও একটি সংরক্ষিত লেনদেন করতে চান। আপনি যদি কোনও এসপিতে লেনদেন করেন এবং এসপি অন্য কোনও লেনদেনের জিনিসগুলিতে আবৃত হয়ে যায় তবে ব্যর্থ হতে চলেছে। sqlstudies.com/2014/01/06/…
কেনেথ ফিশার

আমাকে এটি নির্দেশ করার জন্য ধন্যবাদ। আমি জানি যে এসকিউএল সার্ভারে কোনও নেস্টেড লেনদেন নেই, তবে আমি SAVE TRANSকমান্ডের প্রভাব সম্পর্কে অবগত ছিলাম না ।
ম্যাক্স ভার্নন 21

8

যদি আপনি সঠিকভাবে নেস্টেড স্টোরড প্রক্রিয়াগুলি পরিচালনা করতে চান যা লেনদেনগুলি পরিচালনা করতে পারে (টি-এসকিউএল বা অ্যাপ কোড থেকে শুরু করা হয়েছে) তবে আপনার নীচের উত্তরে বর্ণিত টেম্পলেটটি অনুসরণ করা উচিত:

আমাদের কি সি # কোড এবং সেই সাথে সঞ্চিত পদ্ধতিতে লেনদেন পরিচালনা করতে হবে?

আপনি এখানে যা চেষ্টা করছেন তার থেকে দুটি পার্থক্য লক্ষ্য করবেন:

  1. ব্যবহারের RAISERRORমধ্যে CATCHব্লক। এটি কলিং স্তর পর্যন্ত ত্রুটিটি বুদ্বুদ্বিত করে (ডিবি বা অ্যাপ্লিকেশন স্তরের মধ্যে থাকুক) যাতে কোনও ত্রুটি ঘটেছে তা নিয়ে সিদ্ধান্ত নেওয়া যেতে পারে।

  2. কোন SAVE TRANSACTION। এটি ব্যবহারের জন্য আমি কখনও কোনও মামলা পাইনি। আমি জানি কিছু লোকেরা এটি পছন্দ করে তবে আমি যে কোনও স্থানে কাজ করেছি এমন কিছুতেই আমি নেস্টেড স্তরের যে কোনও একটিতে ঘটে যাওয়া ত্রুটির ধারণাটি ইঙ্গিত করে যে ইতিমধ্যে যা কাজ হয়েছে তা অবৈধ। SAVE TRANSACTIONআপনি ব্যবহার করে আপনি কেবলমাত্র এই স্টোরড পদ্ধতিটি ডাকার আগেই রাজ্যে ফিরে যাচ্ছেন, বিদ্যমান প্রক্রিয়াটিকে অন্যথায় বৈধ হিসাবে রেখে।

    আপনি যদি আরও বিশদ চান SAVE TRANSACTIONতবে দয়া করে এই উত্তরের তথ্যটি একবার দেখুন:

    3 সঞ্চিত প্রক্রিয়া যখন একটি সঞ্চিত পদ্ধতি থেকে শুরু হয় তখন কীভাবে রোলব্যাক করবেন

    এর সাথে আরেকটি সমস্যা SAVE TRANSACTIONহ'ল তার আচরণের সংক্ষিপ্তসার, যেমন সংরক্ষণের ট্রান্সঅ্যাকশন (জোর যুক্ত করা হয়েছে) এর এমএসডিএন পৃষ্ঠায় উল্লেখ করা হয়েছে :

    ডুপ্লিকেট সেভপয়েন্টের নামগুলি কোনও লেনদেনে অনুমোদিত হয়, তবে একটি রোলব্যাক ট্রান্সঅ্যাকশন বিবৃতি যা সেফপয়েন্টের নামটি নির্দিষ্ট করে কেবল সেই নামটি ব্যবহার করে লেনদেনটিকে সর্বাধিক সাম্প্রতিক সংরক্ষণের ট্রানসেকশনে ফিরে যাবে ।

    অর্থ, প্রতিটি সঞ্চিত পদ্ধতিতে প্রতিটি সেভ পয়েন্ট দেওয়ার জন্য আপনাকে খুব সতর্ক হওয়া দরকার যা সমস্ত সঞ্চিত পদ্ধতিতে সমস্ত সেভ পয়েন্টগুলিতে অনন্য। নিম্নলিখিত উদাহরণগুলি এই বিষয়টিকে চিত্রিত করে।

    এই প্রথম উদাহরণটি দেখায় যে আপনি যখন সেভ পয়েন্ট নামটি পুনরায় ব্যবহার করবেন তখন কী হয়; কেবলমাত্র সর্বনিম্ন-স্তরের সেভ পয়েন্টটি রোলড-ব্যাক হয়।

    IF (OBJECT_ID(N'tempdb..#SaveTranTestA') IS NOT NULL)
    BEGIN
        DROP TABLE #SaveTranTestA;
    END;
    CREATE TABLE #SaveTranTestA (SomeVal INT NOT NULL);
    
    BEGIN TRAN; -- start level 1
    SAVE TRANSACTION MySavePoint;
    
    SELECT @@TRANCOUNT AS [TranCount]; -- 1
    
    INSERT INTO #SaveTranTestA (SomeVal) VALUES (100);
    
    BEGIN TRAN; -- start level 2
    SAVE TRANSACTION MySavePoint;
    
    SELECT @@TRANCOUNT AS [TranCount]; -- 2
    
    INSERT INTO #SaveTranTestA (SomeVal) VALUES (200);
    
    COMMIT; -- exit level 2
    
    SELECT @@TRANCOUNT AS [TranCount]; -- 1
    SELECT * FROM #SaveTranTestA;
    -- 100
    -- 200
    
    ROLLBACK TRANSACTION MySavePoint; -- error occurred; undo actions up to this point
    
    SELECT @@TRANCOUNT AS [TranCount]; -- 1
    SELECT * FROM #SaveTranTestA;
    -- 100
    
    COMMIT; -- exit level 1
    
    SELECT @@TRANCOUNT AS [TranCount]; -- 0
    SELECT * FROM #SaveTranTestA;
    -- 100

    এই দ্বিতীয় উদাহরণটি দেখায় যে যখন আপনি অনন্য সেভ পয়েন্টের নাম ব্যবহার করেন তখন কী হয়; পছন্দসই স্তরের সেভ পয়েন্টটি ঘূর্ণিত-ফিরে হয়েছে।

    IF (OBJECT_ID(N'tempdb..#SaveTranTestB') IS NOT NULL)
    BEGIN
        DROP TABLE #SaveTranTestB;
    END;
    CREATE TABLE #SaveTranTestB (SomeVal INT NOT NULL);
    
    BEGIN TRAN; -- start level 1
    SAVE TRANSACTION MySavePointUno;
    
    SELECT @@TRANCOUNT AS [TranCount]; -- 1
    
    INSERT INTO #SaveTranTestB (SomeVal) VALUES (100);
    
    BEGIN TRAN; -- start level 2
    SAVE TRANSACTION MySavePointDos;
    
    SELECT @@TRANCOUNT AS [TranCount]; -- 2
    
    INSERT INTO #SaveTranTestB (SomeVal) VALUES (200);
    
    COMMIT; -- exit level 2
    
    SELECT @@TRANCOUNT AS [TranCount]; -- 1
    SELECT * FROM #SaveTranTestB;
    -- 100
    -- 200
    
    ROLLBACK TRANSACTION MySavePointUno; --error occurred; undo actions up to this point
    
    SELECT @@TRANCOUNT AS [TranCount]; -- 1
    SELECT * FROM #SaveTranTestB;
    -- <no rows>
    
    COMMIT; -- exit level 1
    
    SELECT @@TRANCOUNT AS [TranCount]; -- 0
    SELECT * FROM #SaveTranTestB;
    -- <no rows>

এজন্য আমি আমার সংরক্ষণের ট্রান্সএ্যাকশন সেভপয়েন্টের নাম বানোয়াট করতে @@ নেস্টলেভেল ব্যবহার করি।
ভিনসেন্ট ভ্যাঙ্কালবার্গ
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.