【问题标题】:Need the object name that is producing the error within a try catch block of an sql server stored procedure需要在 sql server 存储过程的 try catch 块中产生错误的对象名称
【发布时间】:2016-10-11 18:36:28
【问题描述】:

我创建了一个更新数据库结构的存储过程。在 try/catch 块中,如果发生错误,我可以获得 ERROR_MESSAGE() 值,但它没有指定错误发生的位置或对象。 ERROR_NUMBER() 函数没有用,因为行号偏离了很多。

是否可以识别正在创建的对象或它失败的语句? 下面是一个 try catch 块的小例子:

BEGIN TRY
BEGIN TRANSACTION 

ALTER TABLE [dbo].[Activity] WITH CHECK ADD CONSTRAINT [FK_dbo.Activity_dbo.Application_ApplicationId] FOREIGN KEY ([ApplicationId]) REFERENCES [dbo].[Application] ([ApplicationId]) ON DELETE CASCADE 
ALTER TABLE [dbo].[Activity] CHECK CONSTRAINT [FK_dbo.Activity_dbo.Application_ApplicationId] 

ALTER TABLE [dbo].[ApplicationCategory] WITH CHECK ADD CONSTRAINT [FK_ApplicationCategory_Application] FOREIGN KEY ([ApplicationId]) REFERENCES [dbo].[Application] ([ApplicationId]) 
ALTER TABLE [dbo].[ApplicationCategory] CHECK CONSTRAINT [FK_ApplicationCategory_Application] 

ALTER TABLE [dbo].[Contacts] WITH CHECK ADD CONSTRAINT [FK_Contacts_Product] FOREIGN KEY ([ProductId]) REFERENCES [dbo].[Product] ([ProductId]) 
ALTER TABLE [dbo].[Contacts] CHECK CONSTRAINT [FK_Contacts_Product] 

ALTER TABLE [dbo].[Frame] WITH CHECK ADD CONSTRAINT [FK_dbo.Frame_dbo.Product_ProductId] FOREIGN KEY ([ProductId]) REFERENCES [dbo].[Product] ([ProductId]) 
ALTER TABLE [dbo].[Frame] CHECK CONSTRAINT [FK_dbo.Frame_dbo.Product_ProductId] 

ALTER TABLE [dbo].[FramesMarkup] WITH CHECK ADD CONSTRAINT [FK_dbo.FramesMarkup_dbo.Manufacturer_ManufacturerId] FOREIGN KEY ([ManufacturerId]) REFERENCES [dbo].[Manufacturer] ([ManufacturerId]) 
ALTER TABLE [dbo].[FramesMarkup] CHECK CONSTRAINT [FK_dbo.FramesMarkup_dbo.Manufacturer_ManufacturerId] 

ALTER TABLE [dbo].[InventoryDecrement] WITH CHECK ADD CONSTRAINT [FK_dbo.InventoryDecrement_dbo.Inventory_InventoryId] FOREIGN KEY ([InventoryId]) REFERENCES [dbo].[Inventory] ([InventoryId]) 
ALTER TABLE [dbo].[InventoryDecrement] CHECK CONSTRAINT [FK_dbo.InventoryDecrement_dbo.Inventory_InventoryId] 

ALTER TABLE [dbo].[Lens] WITH CHECK ADD CONSTRAINT [FK_dbo.Lens_dbo.Rx_RxId] FOREIGN KEY ([RxId]) REFERENCES [dbo].[Rx] ([RxId]) ON DELETE CASCADE 
ALTER TABLE [dbo].[Lens] CHECK CONSTRAINT [FK_dbo.Lens_dbo.Rx_RxId] 

COMMIT TRANSACTION
END TRY
BEGIN CATCH
SELECT ERROR_NUMBER() AS ErrorNumber, ERROR_MESSAGE() AS ErrorMessage;
ROLLBACK TRANSACTION
END CATCH

错误信息是:Could not create constraint. See previous errors. 我想知道哪个约束失败了。

【问题讨论】:

  • 函数 ERROR_LINE() 可能对您有所帮助。
  • 如果你有多次失败,你只会抓住第一个
  • 没关系。让我试试 ERROR_LINE() - 这会给出行号?
  • 我尝试使用重现脚本创建约束,它给了我明确的信息Msg 4902, Level 16, State 1, Line 4 Cannot find the object "dbo.Activity" because it does not exist or you do not have permissions.
  • ERROR_LINE() 很好。它给了我正确的行号。这个脚本是一个更大的存储过程的一部分。当表创建失败时,它会返回良好的错误消息。但是在创建的约束中,它给出了上述错误。

标签: sql-server error-handling


【解决方案1】:

函数 ERROR_LINE() 可能会对您有所帮助。它返回发生脚本错误的行号。只要脚本没有被不断地编辑,你就可以使用它,导致行号移动。

【讨论】:

    【解决方案2】:

    我用来记录错误的错误函数是error_number、error_severity、error_state、error_line、error_procedure、error_message。

    话虽如此,如果您想知道失败的约束,我会为它创建一个参数,然后在每个约束使用约束名称更新它之前。然后在你的捕获中打印出来。

    【讨论】:

      【解决方案3】:

      您可以在try 块的开头添加@step int = 0 变量。

      并为每个约束增加它。 然后在catch块中输出。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-09-01
        • 2012-08-27
        • 2016-01-28
        相关资源
        最近更新 更多