为什么我的商店程序在封闭在事务块中时会抛出错误?

时间:2017-09-21 09:56:06

标签: c# sql sql-server sql-server-2008 tsql

为什么我的代码会抛出错误:

EXECUTE之后的事务计数表示BEGIN和COMMIT语句的数量不匹配。先前的计数= 1,当前计数= 0

当我删除Transaction块时,它工作正常,但不是那些块。为什么?

我已经测试了它最近2天,但它仍然会引发太多的错误,它应该不会,但它仍然存在。请帮帮我。

代码:

ALTER PROC [dbo].[ContractRegistration] 
@ContractorType_ID tinyint, 
@RegistrationDate  date, 
@ExpiryDate        date, 
@Email             varchar(200), 
@FName             varchar(50), 
@Mobile            varchar(50), 
@Name              varchar(50), 
@CNIC              varchar(20), 
@ContactNo         varchar(20), 
@Password          varchar(200), 
@IsActive          bit                                  = 0, 
@User_ID           smallint, 
@Organization_ID   int, 
@District_ID       smallint, 
@ContractorID      int, 
@EnlistmentNo      varchar(50), 
@Address           varchar(300), 
@OfficeID          int, 
@PECCategoryID     int, 
@PECCategoryNo     varchar(50), 
@CNWEnlistmentNo   varchar(50), 
@NTN               varchar(50), 
@SPCode            [dbo].[ContractorSpecializationCode] READONLY, 
@Doc               [dbo].[ContractorDocuments] READONLY, 
@Farm              varchar(200), 
@TaxExempted       bit, 
@BankCode          varchar(20), 
@BankName          varchar(20), 
@BankDraft         varchar(30), 
@Amount            money, 
@RenwalID          int                                  = 0, 
@ExpectedDate      date=null, 
@PecReciptNo       varchar(50),
@IsRenewal BIT,
@RoleID int= 2
AS
BEGIN
  Begin Try
    Begin Transaction tran1
/*
THIS STORED PROCEDURE IS CALLED FOR CONTRACTOR SAVING, UPDATION AND RENWAL...
-- IN CASE OF RENEWAL OLD REGISTRATION, OLD SPECIALZATION CODE AND OLD DOCUMENTS HISTORY IS MAINTAINED IN HISTORY TABLES.
-- IN CASE OF SAVING NEW ENTRY IS DONE, IN CONTRACTOR, SPECIALZATION CODES AND DOCUMENTS.
-- IN CASE OF UPDATION REGISTION SPECIALZTION AND DOUCMENTS ARE UPDATED..
*/
    /* Constractor Status
    1: New
    2 : Approved
    3: Deffered
    4: Rejected
    5 : Approved with c&W Exemption
    */

    ----------------------------- PEC Cat and Category validation
        if(@PECCategoryID = 1 AND (@ContractorType_ID NOT BETWEEN 1 AND 10))
        Begin
                RAISERROR('Category must be between PK-1 and PK-10 for C-A ',16,1);
                RETURN;
        End
        if(@PECCategoryID = 2 AND (@ContractorType_ID NOT BETWEEN 2 AND 10))
        Begin
                RAISERROR('Category must be between PK-2 and PK-10 for C-B ',16,1);
                RETURN;
        End
        if(@PECCategoryID = 3 AND (@ContractorType_ID NOT BETWEEN 3 AND 10))
        Begin
                RAISERROR('Category must be between PK-3 and PK-10 for C-1 ',16,1);
                RETURN;
        End
        if(@PECCategoryID = 4 AND (@ContractorType_ID NOT BETWEEN 4 AND 10))
        Begin
                RAISERROR('Category must be between PK-4 and PK-10 for C-2 ',16,1);
                RETURN;
        End
        if(@PECCategoryID = 5 AND (@ContractorType_ID NOT BETWEEN 5 AND 10))
        Begin
                RAISERROR('Category must be between PK-5 and PK-10 for C-3',16,1);
                RETURN;
        End
        if(@PECCategoryID = 6 AND (@ContractorType_ID NOT BETWEEN 6 AND 10))
        Begin
                RAISERROR('Category must be between PK-6 and PK-10 for C-4 ',16,1);
                RETURN;
        End
        if(@PECCategoryID = 7 AND (@ContractorType_ID NOT BETWEEN 7 AND 10))
        Begin
                RAISERROR('Category must be between PK-7 and PK-10 for C-5 ',16,1);
                RETURN;
        End
        if(@PECCategoryID = 8 AND (@ContractorType_ID NOT BETWEEN 8 AND 10))
        Begin
                RAISERROR('Category must be between PK-8 and PK-10 for C-6 ',16,1);
                RETURN;
        End




    ----------------------------- PEC Cat and Category validation

DECLARE @CurrentStatus int,@HistoryID int;
    -------- If New Entry...
IF @IsRenewal=0
    BEGIN
        IF EXISTS(SELECT ContractorID FROM dbo.Contractors WHERE ContractorID = @ContractorID)
        BEGIN

        ----- SMS section (if contractor mobile no has been modified then sms must be sent to the contractor and MIS manager)

                Declare @OldMobileNo varchar(20)
                Set @OldMobileNo= ISNULL((Select c.ContactNo from Contractors c where c.ContractorID= @ContractorID),0)

                IF(@OldMobileNo not like @Mobile)
                Begin

                       Declare @ContractorName varchar(200)
                       Set @ContractorName= (Select c.Name from dbo.Contractors c where c.ContractorID= @ContractorID)

                       Declare @OrganizationID int
                       Set @OrganizationID= (Select c.Organization_ID from dbo.Contractors c where c.ContractorID= @ContractorID)

                       DECLARE @smsbody NVARCHAR(MAX);
                       Declare @smsbody_MIS NVARCHAR(MAX);                 

                       SET @smsbody = 'Your mobile no. has been changed to '+ @Mobile +'. '+'If you have any query regarding this change then contact system admin.'
                       SET @smsbody_MIS= @ContractorName + ' '+ 'mobile no. has been changed to '+ @Mobile 

                       Declare @EntryDate date
                       Set @EntryDate= (Select GETDATE())

                       EXEC MC_SMS.App.SaveQueueSMSSingle @smsbody,@OldMobileNo,1,1,1,0, @EntryDate, @OrganizationID
                       EXEC MC_SMS.App.SaveQueueSMSSingle @smsbody_MIS,'03369883499',1,1,1,0, @EntryDate, @OrganizationID -- send a copy to MIS manager

                 End

       ----- SMS section



            DELETE FROM [dbo].[SpecializationCodeContractor]
            WHERE Contractor_ID = @ContractorID;
            DELETE FROM [dbo].[DocumentContractor]
            WHERE Contractor_ID = @ContractorID;
            --delete from dbo.ContractorRenewal where  ID=@RenwalID

            UPDATE [dbo].[Contractors]
              SET [ContractorType_ID] = @ContractorType_ID, [RegistrationDate] = @RegistrationDate, [RegExpiryDate] = @ExpiryDate, [Name] = @Name, [FatherName] = @FName, 
              [CNIC] = @CNIC, [ContactNo] = @Mobile, [PhoneNo] = @ContactNo, [EnlistmentNo] = @EnlistmentNo, 
            [Password] = @Password, [Organization_ID] = @Organization_ID, [DistrictID] = @District_ID, [User_ID] = @User_ID, [Office_ID] = @OfficeID, 
            [Address] = @Address, [Email] = @Email, [PecCategoryID] = @PECCategoryID, [PECCategoryNo] = @PECCategoryNo, 
            [CNWEnlistmentNo] = @CNWEnlistmentNo, [NTN] = @NTN, [HasTaxExempted] = @TaxExempted, [Farm] = @Farm,UpdatedBy=@User_ID, UpdatedDate=GETDATE()
            WHERE ContractorID = @ContractorID;

                ----------------------------------------- Maintain History
            INSERT INTO ContractorsHistory (ContractorID, ContractorType_ID, RegistrationDate, RegExpiryDate, Name, FatherName, CNIC, ContactNo, PhoneNo, EnlistmentNo, Password, 
            Organization_ID, DistrictID, User_ID, IsActive, EntryDateTime, LastLoginDate, Office_ID, Address, Email, PECCategoryID, PECCategoryNo, CNWEnlistmentNo, NTN, Status, HasTaxExempted, Farm, ApprovedBy, ApprovedDate, PECReceiptNo, ExpectedDate,UpdatedBy,UpdateDate)
            SELECT ContractorID, ContractorType_ID, RegistrationDate, RegExpiryDate, Name, FatherName, CNIC, ContactNo, PhoneNo, EnlistmentNoNew, Password, 
            Organization_ID, DistrictID, User_ID, IsActive, EntryDateTime, LastLoginDate, Office_ID, Address, Email,PECCategoryID, PECCategoryNo, CNWEnlistmentNo, NTN, Status, HasTaxExempted, Farm, ApprovedBy, ApprovedDate, PECReceiptNo, ExpectedDate,UpdatedBy,UpdatedDate 
            FROM Contractors WHERE ContractorID=@ContractorID;

            SELECT @CurrentStatus = Status
            FROM Contractors
            WHERE ContractorID = @ContractorID;

            IF @CurrentStatus = 5 ---5 : Approved with c&W Exemption
            BEGIN
                INSERT INTO dbo.SpecializationCodeContractor
                       SELECT SP_ID, @ContractorID
                       FROM @SPCode s
                       JOIN SpecializationCodes SP ON SP.SpecializationID = S.SP_ID
                       WHERE SP.SpecCategory_ID = 4; -----Electrical Engineering
            END;
            ELSE
            BEGIN
                INSERT INTO dbo.SpecializationCodeContractor
                       SELECT SP_ID, @ContractorID
                       FROM @SPCode;
            END;
            INSERT INTO [dbo].[DocumentContractor]
                   SELECT Doc_ID, @ContractorID
                   FROM @Doc;

            -- insert into [dbo].[ContractorRenewal]
            -- select @ContractorID,@BankCode,@BankName,@BankDraft,@ExpiryDate,@Amount,GETDATE()


            UPDATE [dbo].[ContractorRenewal]
              SET [BankCode] = @BankCode, [BankName] = @BankName, [BankDraftNo] = @BankDraft, [ValidUpto] = @ExpiryDate, [Amount] = @Amount, [RenwalDate] = @RegistrationDate
            WHERE ID = @RenwalID;

        END;
        ELSE
        BEGIN   --- save new contractor

            -------------------auto enlistment no generation------------------
            declare @MaxContractorID int
            Set @MaxContractorID= (SELECT ISNULL(max(c.contractorID),0) FROM Contractors c where Office_ID= @OfficeID)

            declare @CurrentYear varchar(4)
            Set @CurrentYear = (Select YEAR(getdate()))

            declare @EnlistmentNoNew varchar(20)    --- format= OfficeIDCurrentYearMaxContractorID
            set @EnlistmentNoNew= (Select CAST(@OfficeID as varchar) + @CurrentYear + CAST(@MaxContractorID as varchar))

            -------------------auto enlistment no generation------------------

            INSERT INTO [dbo].[Contractors]([ContractorType_ID], [RegistrationDate], [RegExpiryDate], [Name], [FatherName], [CNIC], [ContactNo], [PhoneNo], [EnlistmentNo], 
            [Password], [Organization_ID], [DistrictID], [User_ID], [IsActive], [EntryDateTime], [LastLoginDate], [Office_ID], [address], [Email], [PECCategoryID], 
            [PECCategoryNo], [CNWEnlistmentNo], [ntn], [HasTaxExempted], [Status], [Farm], PECReceiptNo, ExpectedDate, EnlistmentNoNew)
            VALUES(@ContractorType_ID, @RegistrationDate, @ExpiryDate, @Name, @FName, @CNIC, @Mobile, @ContactNo, @EnlistmentNo, @Password, @Organization_ID, @District_ID, 
            @User_ID, 0, GETDATE(), GETDATE(), @OfficeID, @Address, @Email, @PECCategoryID, @PECCategoryNo, @CNWEnlistmentNo, @NTN, @TaxExempted, 1, @Farm, 
            @PecReciptNo, @ExpectedDate, @EnlistmentNoNew);

            DECLARE @Con_ID int;
            SELECT @Con_ID = IDENT_CURRENT('[dbo].[Contractors]');
            ----------------------------------------- Maintain History
            INSERT INTO ContractorsHistory (ContractorID, ContractorType_ID, RegistrationDate, RegExpiryDate, Name, FatherName, CNIC, ContactNo, PhoneNo, EnlistmentNo, Password, 
            Organization_ID, DistrictID, User_ID, IsActive, EntryDateTime, LastLoginDate, Office_ID, Address, Email, PECCategoryID, PECCategoryNo, CNWEnlistmentNo, NTN, Status, HasTaxExempted, Farm, ApprovedBy, ApprovedDate, PECReceiptNo, ExpectedDate)
                                     SELECT ContractorID, ContractorType_ID, RegistrationDate, RegExpiryDate, Name, FatherName, CNIC, ContactNo, PhoneNo, EnlistmentNoNew, Password, 
                                     Organization_ID, DistrictID, User_ID, IsActive, EntryDateTime, LastLoginDate, Office_ID, Address, Email, PECCategoryID, PECCategoryNo, CNWEnlistmentNo, NTN, Status, HasTaxExempted, Farm, ApprovedBy, ApprovedDate, PECReceiptNo, ExpectedDate 
                                     FROM Contractors WHERE ContractorID=@Con_ID;

            Set @HistoryID= IDENT_CURRENT('ContractorsHistory')

            INSERT INTO dbo.SpecializationCodeContractor
                   SELECT SP_ID, @Con_ID
                   FROM @SPCode;

            INSERT INTO [dbo].[DocumentContractor]
                   SELECT Doc_ID, @Con_ID
                   FROM @Doc;

            IF @Amount > 0
            BEGIN
                INSERT INTO [dbo].[ContractorRenewal](Contractor_ID,BankCode,BankName,BankDraftNo,ValidUpto,Amount,RenwalDate,ContractorHistory_ID)
                       SELECT @Con_ID, @BankCode, @BankName, @BankDraft, @ExpiryDate, @Amount, @RegistrationDate,@HistoryID;
            END;

        END;
    END
    ELSE
    ----- Renewal Section...
    BEGIN
    --------------- Maintain Previous Year Documents and Specializtion COde in History Tables..
    SELECT TOP  1 @HistoryID=HistoryID FROM ContractorsHistory WHERE ContractorID=@ContractorID ORDER BY HistoryID DESC;
        ----------------- Specialization Code history...
        INSERT INTO SpecializationCodeContractorHistory (SP_ID,Contractor_ID,ContractorHistory_ID)
        SELECT SP_ID,Contractor_ID,@HistoryID from SpecializationCodeContractor WHERE Contractor_ID=@ContractorID;
        ---------------------- Documents History.....

        INSERT INTO DocumentContractorHistory (Doc_ID,Contractor_ID,ContractorHistory_ID)
        SELECT Doc_ID,Contractor_ID,@HistoryID FROM DocumentContractor WHERE Contractor_ID=@ContractorID;
        ----------------------

        -------------------auto enlistment no generation------------------
            declare @MaxContractorID1 int
            Set @MaxContractorID1= (SELECT ISNULL(max(c.contractorID),0) FROM Contractors c where Office_ID= @OfficeID)

            declare @CurrentYear1 varchar(4)
            Set @CurrentYear1 = (Select YEAR(getdate()))

            declare @EnlistmentNoNew1 varchar(20)    --- format= OfficeIDCurrentYearMaxContractorID
            set @EnlistmentNoNew1= (Select CAST(@OfficeID as varchar) + @CurrentYear1 + CAST(@MaxContractorID1 as varchar))
        -------------------auto enlistment no generation------------------

            UPDATE [dbo].[Contractors]
              SET [ContractorType_ID] = @ContractorType_ID, [RegistrationDate] = @RegistrationDate, [RegExpiryDate] = @ExpiryDate, [Name] = @Name, [FatherName] = @FName, 
              [CNIC] = @CNIC, [ContactNo] = @Mobile, [PhoneNo] = @ContactNo, [EnlistmentNo] = @EnlistmentNo, 
            [Password] = @Password, [Organization_ID] = @Organization_ID, [DistrictID] = @District_ID, [User_ID] = @User_ID, [Office_ID] = @OfficeID, 
            [Address] = @Address, [Email] = @Email, [PecCategoryID] = @PECCategoryID, [PECCategoryNo] = @PECCategoryNo, 
            [CNWEnlistmentNo] = @CNWEnlistmentNo, [NTN] = @NTN, [HasTaxExempted] = @TaxExempted, [Farm] = @Farm,UpdatedBy=@User_ID,UpdatedDate=GETDATE(), EnlistmentNoNew=@EnlistmentNoNew1
            WHERE ContractorID = @ContractorID;

        ----------- Save History...
        INSERT INTO ContractorsHistory (ContractorID, ContractorType_ID, RegistrationDate, RegExpiryDate, Name, FatherName, CNIC, ContactNo, 
                    PhoneNo, EnlistmentNo, Password, Organization_ID, DistrictID, User_ID, IsActive, EntryDateTime, LastLoginDate, Office_ID, 
                    Address, Email, PECCategoryID, PECCategoryNo, CNWEnlistmentNo, NTN, Status, HasTaxExempted, Farm, ApprovedBy, ApprovedDate, PECReceiptNo, ExpectedDate,UpdateDate,UpdatedBy)
        SELECT ContractorID, ContractorType_ID, RegistrationDate, RegExpiryDate, Name, FatherName, CNIC, ContactNo, PhoneNo, EnlistmentNoNew, 
                    Password, Organization_ID, DistrictID, User_ID, IsActive, EntryDateTime, LastLoginDate, Office_ID, Address, Email, PECCategoryID, 
                    PECCategoryNo, CNWEnlistmentNo, NTN, Status, HasTaxExempted, Farm, ApprovedBy, ApprovedDate, PECReceiptNo, ExpectedDate,UpdatedDate,UpdatedBy FROM Contractors
        WHERE ContractorID=@ContractorID;


        DELETE FROM [dbo].[SpecializationCodeContractor]
        WHERE Contractor_ID = @ContractorID;
        ----------------------------------------
        DELETE FROM [dbo].[DocumentContractor]
        WHERE Contractor_ID = @ContractorID;
            --delete from dbo.ContractorRenewal where  ID=@RenwalID

            SELECT @CurrentStatus = Status
            FROM Contractors
            WHERE ContractorID = @ContractorID;

            IF @CurrentStatus = 5 ---5 : Approved with c&W Exemption
            BEGIN
                INSERT INTO dbo.SpecializationCodeContractor
                       SELECT SP_ID, @ContractorID
                       FROM @SPCode s
                       JOIN SpecializationCodes SP ON SP.SpecializationID = S.SP_ID
                       WHERE SP.SpecCategory_ID = 4; -----Electrical Engineering
            END;
            ELSE
            BEGIN
                INSERT INTO dbo.SpecializationCodeContractor
                       SELECT SP_ID, @ContractorID
                       FROM @SPCode;
            END;
            INSERT INTO [dbo].[DocumentContractor]
                   SELECT Doc_ID, @ContractorID
                   FROM @Doc;

            -- insert into [dbo].[ContractorRenewal]
            -- select @ContractorID,@BankCode,@BankName,@BankDraft,@ExpiryDate,@Amount,GETDATE()

            IF EXISTS(SELECT Contractor_ID FROM ContractorRenewal WHERE ValidUpto=@ExpiryDate AND Contractor_ID=@ContractorID)
            BEGIN
                RAISERROR('Payment Entry already exists for selected Renewal Year!',16,1);
                RETURN;
            END
            ELSE
            BEGIN
                INSERT INTO [dbo].[ContractorRenewal] (Contractor_ID,BankCode,BankName,BankDraftNo,ValidUpto,Amount,RenwalDate)
                VALUES  ( @ContractorID, @BankCode, @BankName, @BankDraft, @ExpiryDate, @Amount, @RegistrationDate);
            END
        END

    Commit Transaction 

 End Try
 Begin Catch
    rollback transaction
 End Catch
END;

更新:根据建议:

C#end

public static bool SaveContractor(clsAdmin A, bool IsRenewal = false)
{
    SqlCommand com = new SqlCommand("[dbo].ContractRegistration", OpenConnection());
    bool result = false;
    SqlTransaction tran = conn.BeginTransaction();
    try
    {
        com.Transaction = tran;
        // // Passing DataTable to SP...
        SqlParameter sp = com.Parameters.AddWithValue("@SPCode", A.dt);
        sp.SqlDbType = SqlDbType.Structured;
        SqlParameter sp1 = com.Parameters.AddWithValue("@Doc", A.dtDoc);
        sp1.SqlDbType = SqlDbType.Structured;
        com.Parameters.AddWithValue("@ContractorID", A.ContractorID);
        com.Parameters.AddWithValue("@ContractorType_ID", A.CategoryID);
        com.Parameters.AddWithValue("@RegistrationDate", A.RegistractionDate);
        com.Parameters.AddWithValue("@ExpiryDate", A.ExpiryDate);
        com.Parameters.AddWithValue("@Email", A.Email);
        com.Parameters.AddWithValue("@FName", A.FName);
        com.Parameters.AddWithValue("@Mobile", A.Mobile);
        com.Parameters.AddWithValue("@Name", A.Name);
        com.Parameters.AddWithValue("@CNIC", A.CNIC);
        com.Parameters.AddWithValue("@ContactNo", A.Contact);
        com.Parameters.AddWithValue("@Password", A.Password);
        com.Parameters.AddWithValue("@IsActive", 1);
        com.Parameters.AddWithValue("@User_ID", A.UserID);
        com.Parameters.AddWithValue("@Organization_ID", A.OrganizationID);
        com.Parameters.AddWithValue("@District_ID", A.DistrictID);
        com.Parameters.AddWithValue("@EnlistmentNo", A.EnlistmentNo);
        com.Parameters.AddWithValue("@Address", A.Address);
        com.Parameters.AddWithValue("@OfficeID", A.OfficeID);
        com.Parameters.AddWithValue("@PECCategoryID", A.PECCategoryID);
        com.Parameters.AddWithValue("@PECCategoryNo", A.PECCategoryNo);
        com.Parameters.AddWithValue("@CNWEnlistmentNo", A.CNWEnlistmentNo);
        com.Parameters.AddWithValue("@NTN", A.NTN);
        com.Parameters.AddWithValue("@Farm", A.Farm);
        com.Parameters.AddWithValue("@TaxExempted", A.TaxExe);
        com.Parameters.AddWithValue("@BankCode", A.BankCode);
        com.Parameters.AddWithValue("@BankName", A.BankName);
        com.Parameters.AddWithValue("@BankDraft", A.BankDraftNo);
        com.Parameters.AddWithValue("@Amount", A.Amount);
        com.Parameters.AddWithValue("@RenwalID", A.ReID);
        com.Parameters.AddWithValue("@PecReciptNo", A.PecReciptNo);
        com.Parameters.AddWithValue("@ExpectedDate", A.ExpectedDate);
        com.Parameters.AddWithValue("@IsRenewal", IsRenewal);
        com.Parameters.AddWithValue("@RoleID", A.RoleID);

        com.CommandType = CommandType.StoredProcedure;
        result = com.ExecuteNonQuery().ToBool();
        tran.Commit();
        CloseConnection();
    }
    catch (Exception ex)
    {
        tran.Rollback();
        CloseConnection();
        throw ex;

    }
    return result;
}

1 个答案:

答案 0 :(得分:0)

您已在应用程序代码中使用事务,这就是为什么当您在过程中提交或回滚事务时,应用程序代码无法提交任何内容。你得到了这个例外。

实际上,您在程序中不需要任何额外的交易。其中一个就足够了。