执行存储过程时收到以下错误消息:
[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?
您对我有什么建议吗?