【发布时间】:2014-08-01 16:15:44
【问题描述】:
我有两个存储过程,一个嵌套在另一个内部。目前,当调用嵌套存储过程时,它应该因违反外键约束而出错,然后回滚先前的调用以插入到 ProductLicense 表中。由于外键冲突,嵌套过程不会对数据库执行任何操作,但调用存储过程没有捕获错误并回滚。如果我自己执行嵌套存储过程,它会返回错误 547 外键违规。
如何让这两个存储过程一起工作?
外部程序:
ALTER PROCEDURE [dbo].[AddNewLicense2_i]
-- Add the parameters for the stored procedure here
@customerId nvarchar(10),
@licenseModeId int,
@licenseModeProgramId int,
@createdBy int,
@updateBy int,
@systemId nvarchar(50),
@productId int
AS
BEGIN TRY
BEGIN TRANSACTION
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;
--SET XACT_ABORT ON; --used for automatic rollback when an error occurs
DECLARE @tempDays INT
DECLARE @programCornerAmt INT
DECLARE @tempEndDate DATETIME
DECLARE @tempExpDate DATETIME
DECLARE @err INT
SET @err = 0
/*SET @tempDays = (SELECT lmp.TimeoutDays
FROM LicenseModeProgram lmp
WHERE lmp.LicenseModeProgramId = @licenseModeProgramId)*/
SELECT @tempDays = TimeoutDays, @programCornerAmt = MonthlyCornersAmount
FROM LicenseModeProgram
WHERE LicenseModeProgramId = @licenseModeProgramId
--Build Expiration and End Dates.
IF @tempDays = NULL --then this is NOT a time rental or metered system
BEGIN
SET @tempEndDate = NULL
SET @tempExpDate = NULL
END
ELSE
BEGIN
SET @tempEndDate = DATEADD("d", @tempDays, GETDATE())
SET @tempExpDate = DATEADD("d", @tempDays, GETDATE())
END
-- Create new product license record
INSERT INTO ProductLicense (CustomerId, LicenseModeId, LicenseModeProgramId, CreatedBy, UpdatedBy, SystemId, ProductId, ExpirationDate, LicenseEndDate)
VALUES (@customerId, @licenseModeId, @licenseModeProgramId, @createdBy, @updateBy, @systemId, @productId, @tempExpDate, @tempEndDate)
IF @licenseModeId = 4 AND @systemId NULL AND @programCornerAmt NULL
--call stored procedure to add corners to the customer account
EXECUTE @err = AddMeteredTx_i @systemId, 1, 1, @programCornerAmt , 'Initial License Creation'
PRINT @err
COMMIT TRANSACTION
END TRY
BEGIN CATCH
RAISERROR('Failed to Create License', 11, 2)
ROLLBACK TRANSACTION
RETURN 1
END CATCH
--COMMIT TRANSACTION
RETURN 0
GO
内部程序:
ALTER PROCEDURE [dbo].[AddMeteredTx_i]
-- Add the parameters for the stored procedure here
@systemId nvarchar(50),
@activityEventId int,
@createdBy int,
@amount int,
@notes text
AS
BEGIN TRY
BEGIN TRANSACTION
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;
--SET XACT_ABORT ON; --used for automatic rollback when an error occurs
INSERT INTO CustomerAccountActivity (SystemId, ActivityEventId, CreatedBy, Amount, Notes)
VALUES (@systemId, @activityEventId, @createdBy, @amount, @notes)
UPDATE CustomerAccount
SET MeteredBalance = (SELECT MeteredBalance FROM CustomerAccount WHERE SystemId = @systemId) + @amount
WHERE SystemId = @systemId
COMMIT TRANSACTION
END TRY
BEGIN CATCH
RAISERROR('Error Update to Customer Account Record ', 11, 2)
ROLLBACK TRANSACTION
RETURN 1
--COMMIT TRANSACTION
END CATCH
RETURN 0
GO
【问题讨论】:
-
我们还需要查看外部过程的代码。
-
另外,请避免使用
@@ERROR来检测错误,TRY/CATCH更加健壮。 -
对不起,我刚刚添加了它。
标签: sql sql-server stored-procedures