存储过程失败(可能是由于嵌套的事务/提交)

时间:2020-01-15 15:15:23

标签: sql-server

执行存储过程时收到以下错误消息:

[SQLSTATE 25000](错误3902)
COMMIT TRANSACTION请求没有相应的BEGIN TRANSACTION。

这是我的存储过程的样子:

SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO

ALTER PROCEDURE [InputData].[Update_eFile_Cesar]
AS
BEGIN
    SET NOCOUNT ON;

    Declare @CommNr nvarchar(10);
    Declare @VSBOrderKey int;
    Declare @CesarOrderKey int;
    Declare @PK_Checklist int;
    Declare @OLD_PreOrder nvarchar(20);
    Declare @NEW_PreOrder nvarchar(20);

    select ons.CommissionNumber, binary_checksum(co.OrderDate,co.[NationalType],co.[CustomerNumber],co.[Firstname],co.[Surname],co.[CompanyName],co.[LeasingCompanyNumber]
                    ,co.[LeasingCompanyName],co.[FleetNumber],co.[FleetNumberNational],co.[ContractSignOffDate],co.[VehicleUsage],co.[OrderStatus]
                    ,co.[EstimatedDeliveryDate],co.[DeliveryDate],co.[DestinationKey],co.[FinalProductionDate],co.[ProductionDecade],co.[ChassisNumber]
                    ,co.[VehicleDescription],ons.PreOrderNumber)  AS 'CheckSumSAM',ons.PreOrderNumber AS 'OLD_PreOrder', co.PK_OrderCesar AS 'CesarOrderKey',
                    binary_checksum(o.OrderDate, v.NationalType, c.CustomerNumber, c.FirstName, c.Surname, c.CompanyName, c.LeasingCompanyNumber
                    , c.LeasingCompanyName, c.FleetNumber,c.FleetNumberNational, c.ContractSignOffDate, o.VehicleUsage, o.OrderStatus
                    , o.EstimatedDeliveryDate, o.DeliveryDate, o.DestinationKey, o.FinalProductionDate
                    ,o.ProductionDecade, v.ChassisNumber, v.VehicleDescription, o.PreOrderNumber) AS 'CheckSumLDS',
                    o.PreOrderNumber AS 'NEW_PreOrder' into #temptable2
        FROM [sam].[CesarOrders] co 
        INNER JOIN [sam].[VehicleFiles] vf on co.PK_OrderCesar = vf.FK_OrderCesar
        INNER JOIN [dbo].[OrderNumbers] ons on vf.PK_VehicleFile = ons.FK_VehicleFile
        INNER JOIN [LDS_XML].[LDS].[Orders] o on ons.CommissionNumber = o.FactoryOrderNumber
        LEFT JOIN [LDS_XML].[LDS].[Vehicles] v on o.OrderId = v.OrderId
        LEFT JOIN [LDS_XML].[LDS].[Customers] c on o.OrderId = c.OrderId
        --where ons.CommissionNumber = '0651312526'

    Declare Akte_Update_Tabelle CURSOR FOR 
        Select CommissionNumber, OLD_PreOrder, NEW_PreOrder, CesarOrderKey 
        from #temptable2 
        where CheckSumSAM <> CheckSumLDS

    OPEN Akte_Update_Tabelle;

    Fetch next from Akte_Update_Tabelle into @CommNr, @OLD_PreOrder, @NEW_PreOrder, @CesarOrderKey;

    while (@@FETCH_STATUS = 0)
    Begin
        BEGIN TRAN
 ---------------------------------------------------------------
---- OrderCesar Update
---------------------------------------------------------------
--Select 'In der Schleife' as Status, @CommNr as CommNumber, @CesarOrderKey as CESARKey
UPDATE [SAM].[CesarOrders]
   SET [UpdateDate] = getdate()
      ,[OrderDate] = o.OrderDate
      ,[NationalType] = v.NationalType
      ,[CustomerNumber] = c.CustomerNumber
      ,[Firstname] = c.FirstName
      ,[Surname] = c.Surname
      ,[CompanyName] = c.CompanyName
      ,[LeasingCompanyNumber] = c.LeasingCompanyNumber
      ,[LeasingCompanyName] = c.LeasingCompanyName
      ,[FleetNumber] = c.FleetNumber
      ,[FleetNumberNational] = c.FleetNumberNational
      ,[ContractSignOffDate] = c.ContractSignOffDate
      ,[VehicleUsage] = o.VehicleUsage
      ,[OrderStatus] = o.OrderStatus
      ,[EstimatedDeliveryDate] = o.EstimatedDeliveryDate
      ,[DeliveryDate] = o.DeliveryDate
      ,[DestinationKey] = o.DestinationKey
      ,[FinalProductionDate] = o.FinalProductionDate
      ,[ProductionDecade] = o.ProductionDecade
      ,[ChassisNumber] = v.ChassisNumber
      ,[VehicleDescription] = v.VehicleDescription
 FROM [sam].[CesarOrders] co 
 inner join [sam].[VehicleFiles] vf on co.PK_OrderCesar = vf.FK_OrderCesar
 inner join [dbo].[OrderNumbers] ons on vf.PK_VehicleFile = ons.FK_VehicleFile
 inner join [LDS_XML].[LDS].[Orders] o on ons.CommissionNumber = o.FactoryOrderNumber
 left join [LDS_XML].[LDS].[Vehicles] v on o.OrderId = v.OrderId
 left join [LDS_XML].[LDS].[Customers] c on o.OrderId = c.OrderId
 WHERE PK_OrderCesar = @CesarOrderKey 

 -----------------------------------------------------------------
------ Update VehicleFiles mit vorhandener Checkliste oder Calculation
-----------------------------------------------------------------
-- Noch keine Checkliste vorhanden
IF @OLD_PreOrder is NULL and @NEW_PreOrder is not NULL
BEGIN
--Select 'Update'
Update [dbo].[OrderNumbers]
SET [PreOrderNumber] = @NEW_PreOrder
    where [CommissionNumber] = @CommNr
END

-- Für Kontingentfahrzeuge brauchen wir eine Sonderroutine. Zum Zeitpunkt des Anlegens der Checkliste ist dem Verkäufer nur die PreOrder bekannt. Die Checkliste legt
-- einen Datensatz an, der etwa so aussieht: 

--PK_OrderNumber    FK_Checklist    FK_VehicleFile  PreOrderNumber  CommissionNumber    
--56630             2126            NULL            000007129370    NULL        

-- Die PreOrderNummer der umgewidmeten Kommissionsnummern wird erst NACH Anlage der Checkliste vergeben und läuft dann 1 Tag später in OrderNumbers ein. 
-- D.h. es werden zwangsläufig zwei Zeilen angelegt, da die folgende Zeile (allerdings ohne die PreOrderNummer) bereits Wochen oder Monate vor der Checkliste existiert (da Kontingent)

--PK_OrderNumber    FK_Checklist    FK_VehicleFile  PreOrderNumber  CommissionNumber    
--56107             NULL            4132            000007129370    0951380877      

-- Wir brauchen nun eine Routine, die die FK_Checklist der ersten Zeile in die zweite Zeile umhängt:

if ( Select Count(*) from OrderNumbers where PreOrderNumber = @NEW_PreOrder) = 2
BEGIN TRY
    BEGIN TRAN

    Declare @rowWithVehicleID int = (select PK_OrderNumber from OrderNumbers where PreOrderNumber = @NEW_PreOrder AND FK_VehicleFile IS NOT NULL)
    Declare @rowWithChecklistID int = (select PK_OrderNumber from OrderNumbers where PreOrderNumber = @NEW_PreOrder AND FK_Checklist IS NOT NULL)
    Declare @FK_CL int = (select FK_Checklist from OrderNumbers where PK_OrderNumber = @rowWithChecklistID)
        -- 1. Checkliste abhängen
       UPDATE dbo.OrderNumbers 
       SET FK_Checklist = NULL WHERE PK_OrderNumber = @rowWithChecklistID;  

       -- 2. Checkliste mit dem richtigen Datensatz verknüpfen
       UPDATE dbo.OrderNumbers 
       SET FK_Checklist = @FK_CL WHERE PK_OrderNumber = @rowWithVehicleID
       -- 3. Löschen des nun nicht mehr benötigten Datensatzes
       DELETE FROM dbo.OrderNumbers WHERE PK_OrderNumber = @rowWithChecklistID
    COMMIT TRAN
END TRY
BEGIN CATCH
    IF @@TRANCOUNT > 0
        ROLLBACK TRAN --RollBack in case of Error
END CATCH

-- PreOrder bereits vorhanden aber die Neue ist unterschiedlich zur Alten
IF @OLD_PreOrder is not NULL and @OLD_PreOrder <> @NEW_PreOrder
BEGIN
--Select 'Update PreOrder', @CommNr as KomNummer, @OLD_PreOrder as AltePreOrder, @NEW_PreOrder As NeuePreOrder
Update [dbo].[OrderNumbers]
Set [PreOrderNumber]  = @NEW_PreOrder
Where [CommissionNumber] = @CommNr
END

COMMIT TRAN

    Fetch next from Akte_Update_Tabelle into @CommNr, @OLD_PreOrder, @NEW_PreOrder, @CesarOrderKey

END
CLOSE Akte_Update_Tabelle;
DEALLOCATE Akte_Update_Tabelle;

drop table #temptable2

END

在我添加try-catch块之前,Sp运行得很好。我坚信,这就是发生错误的地方。我还相信是嵌套的BEGIN TRAN / COMMIT导致了此错误,但我不知道如何更好地执行此操作。也许只是完全忽略了尝试?还是只在没有特定交易的情况下使用try / catch?

您对我有什么建议吗?

0 个答案:

没有答案