Sql server 部分存储过程没有运行

Sql server 部分存储过程没有运行,sql-server,tsql,stored-procedures,scope-identity,Sql Server,Tsql,Stored Procedures,Scope Identity,我有一个存储过程,它运行一系列插入,但在某些情况下,似乎其中一个插入没有运行,但随后的其余代码运行良好 DECLARE @ID1 int DECLARE @ID2 int -- This works INSERT INTO table1 (field1,field2) VALUES('test', 1) SELECT @ID1 = SCOPE_IDENTITY() -- This picks up the correct ID -- This sometimes doesn't seem t

我有一个存储过程,它运行一系列插入,但在某些情况下,似乎其中一个插入没有运行,但随后的其余代码运行良好

DECLARE @ID1 int
DECLARE @ID2 int

-- This works
INSERT INTO table1 (field1,field2)
VALUES('test', 1)
SELECT @ID1 = SCOPE_IDENTITY() -- This picks up the correct ID

-- This sometimes doesn't seem to run or an error of some sort happens infrequently
INSERT INTO table2 (field1, field2, field3, field4, field5)
VALUES(1,2,3,4,@ID1)

-- This always runs, but if the previous insert doesn't run inserts the previous ID into @ID2
SELECT @ID2 = SCOPE_IDENTITY()

-- Inserts the ID from the previous step and therefore is sometimes wrong
INSERT INTO table3 (field1,field2)
VALUES ('testing', @ID2)
这是SP的修订样本。为什么有时会发生这种情况?我会想,如果插入有问题,程序的其余部分会爆炸?但同样的代码也能工作,大多数时候都是由同一个人运行的。我已经检查了是否有任何表锁定在问题发生的同时进行,但似乎没有任何我可以发现的


找出问题所在的最佳方法是什么?或者我应该如何重新构造上述代码以消除可能的影响?

将TRY/CATCH放在第二个INSERT周围以查看可能的错误。

在INSERT行后检查@error以查看是否抛出了静默错误。 您也可以尝试将插入行包装在try/CATCH块中,但我怀疑这不会有什么效果,因为我假设您在managementstudio的输出窗口中没有收到任何错误

尝试在运行存储过程的同时运行SQL Profiler,以查看它是否提供有关故障的任何进一步信息

以下对存储过程的更改可能会从SP本身中为您提供尽可能多的有关发生了什么的信息。 这不是完美的代码,但它应该提供发生和被吞没的任何错误的适当指示:

DECLARE @ID1 int
DECLARE @ID2 int

-- This works
INSERT INTO table1 (field1,field2)
VALUES('test', 1)
SELECT @ID1 = SCOPE_IDENTITY() -- This picks up the correct ID

-- This sometimes doesn't seem to run
IF @@error <> 0
BEGIN
    PRINT 'Error before: ' + (cast @@error as varchar)
END

BEGIN TRY
    INSERT INTO table2 (field1, field2, field3, field4, field5)
    VALUES(1,2,3,4,@ID1)
END TRY
BEGIN CATCH
    SELECT ERROR_NUMBER() AS ErrorNumber
        ,ERROR_SEVERITY() AS ErrorSeverity
        ,ERROR_STATE() AS ErrorState
        ,ERROR_PROCEDURE() AS ErrorProcedure
        ,ERROR_LINE() AS ErrorLine
        ,ERROR_MESSAGE() AS ErrorMessage;
END CATCH

IF @@error <> 0
BEGIN
    PRINT 'Error after: ' + cast(@@error as varchar)
END

-- This always runs, but if the previous insert doesn't run inserts the previous ID into @ID2
SELECT @ID2 = SCOPE_IDENTITY()

-- Inserts the ID from the previous step and therefore is sometimes wrong
INSERT INTO table3 (field1,field2)
VALUES ('testing', @ID2)

使用try/catch和in-catch语句引发错误。 例如:


在您的表2中有一个主键您可以在执行此查询的同时运行SQL Profiler,并在它无法自动插入时发布您在其中得到的内容吗?表2有一个主键,它是自动递增的。主键字段未插入上述代码中。我现在正在运行SQL Profiler,并插入了一些TRY/CATCH代码来缩小问题范围。但我只能等待问题的发生,因为它并不常见,而且似乎只是随机发生的。我插入了一些TRY/CATCH代码来缩小问题的范围。但是我只能等待问题的发生,因为它并不经常发生,而且似乎只是随机发生的。@另外一个问题是,您可以在插入后立即检查该行是否已添加,如果未添加,请记录@错误的结果。是否将错误消息、错误行等写入日志记录表?这将允许你在一段时间内查看/触发向你发送电子邮件等?是的,这就是我现在正在做的,但问题从那以后就没有出现过。昨天两次,今天一次。如果问题再次出现,我希望看到它。我插入了一些TRY/CATCH代码来缩小问题的范围。但我只能等待问题的发生,因为它并不常见,而且似乎只是随机发生的。我插入了一些TRY/CATCH代码来缩小问题的范围。但我只能等待问题的发生,因为它很少发生,而且似乎只是随机发生的。
CREATE PROC Usp_InsertBulkRecord
AS
BEGIN
BEGIN TRY
    DECLARE @ID1 int
    DECLARE @ID2 int

-- This works
INSERT INTO table1 (field1,field2)
VALUES('test', 1)
SELECT @ID1 = SCOPE_IDENTITY() -- This picks up the correct ID

-- This sometimes doesn't seem to run
INSERT INTO table2 (field1, field2, field3, field4, field5)
VALUES(1,2,3,4,@ID1)

-- This always runs, but if the previous insert doesn't run inserts the previous ID into @ID2
SELECT @ID2 = SCOPE_IDENTITY()

-- Inserts the ID from the previous step and therefore is sometimes wrong
INSERT INTO table3 (field1,field2)
VALUES ('testing', @ID2)
END TRY              
  BEGIN CATCH              
  DECLARE @Error varchar(8000)                                                            
    SET @Error= Convert(varchar,ERROR_NUMBER()) + '*****' + Convert(varchar(4000),ERROR_MESSAGE())                                                             
    + '*****' + isnull(Convert(varchar,ERROR_PROCEDURE()),'[Usp_InsertBulkRecord]')                     
    + '*****' + Convert(varchar,ERROR_LINE()) + '*****' + Convert(varchar,ERROR_SEVERITY())                         
    + '*****' + Convert(varchar,ERROR_STATE())                                                            
    RAISERROR (@Error,16,1);               
  END CATCH 

END