【问题标题】:Return error with OUTPUT from CATCH block从 CATCH 块返回错误与 OUTPUT
【发布时间】:2018-08-23 18:21:39
【问题描述】:

我有一个使用 try/catch 块执行简单插入事务的存储过程。

如果交易成功,OUTPUT会返回插入的记录ID。如果发生错误,我想从 try/catch 块返回内容。在发生错误的情况下,我当前的代码将返回空白RecID。这是我的代码示例:

CREATE PROCEDURE [dbo].[InsertRecord] 
    @Status BIT = NULL,
    @Name VARCHAR(50) = NULL,
    @Code CHAR(2) = NULL,
    @ActionID UNIQUEIDENTIFIER = NULL
AS
    SET NOCOUNT ON
    SET XACT_ABORT ON
    BEGIN TRY
        BEGIN
            INSERT INTO dbo.Dictionary(
                Status,Name,Code,ActionDt,ActionID
            )
            OUTPUT INSERTED.RecID
            VALUES(
                @Status,@Name,@Code,CURRENT_TIMESTAMP,@ActionID
            );
        END
    END TRY
    BEGIN CATCH 
        SELECT  
            ERROR_PROCEDURE() AS ErrorProcedure,
            ERROR_LINE() AS ErrorLine,
            ERROR_NUMBER() AS ErrorNumber,
            ERROR_MESSAGE() AS ErrorMessage,
            CURRENT_TIMESTAMP AS DateTime
    END CATCH

如果我尝试插入已存在的记录,上面的代码将返回以下内容:

ErrorProcedure  
InsertRecord    
ErrorLine   
16              
ErrorNumber 
2627
ErrorMessage    
Violation of PRIMARY KEY constraint 'PK_Code'.  
Cannot insert duplicate key in object 'dbo.Dictionary'.  
The duplicate key value is (44).
DateTime
2018-08-23 10:46:02.920

这是我所期望的,并且在 Management Studio 2008 中显示。当我使用 ColdFusion 调用此过程时,我只得到RecID = ''。这是我如何调用此过程的示例:

<cftry>
    <cfstoredproc procedure="InsertRecord" datasource="#dsn#">
        <cfprocparam dbvarname="@Status" value="#trim(arguments.frm_status)#" cfsqltype="cf_sql_bit" />
        <cfprocparam dbvarname="@Code" value="#trim(arguments.frm_code)#" cfsqltype="cf_sql_char" maxlength="2" null="#!len(trim(arguments.frm_code))#" />
        <cfprocparam dbvarname="@Name" value="#trim(arguments.frm_name)#" cfsqltype="cf_sql_varchar" maxlength="50" null="#!len(trim(arguments.frm_name))#" />
        <cfprocparam dbvarname="@ActionID" value="#trim(SESSION.UserID)#" cfsqltype="cf_sql_idstamp" maxlength="50" null="#!len(trim(SESSION.UserID))#" />
        <cfprocresult name="Result"/>
    </cfstoredproc>

    <cfset local.fnResults = {status : "200", RecID : Result.RecID}>

    <cfcatch type="any">
        <cfset local.fnResults = {error:cfcatch,status : "400", class : "alert-danger", message : "Error! Please contact your administrator."}>
    </cfcatch>
</cftry>

有没有办法在执行后将错误从存储过程返回给 ColdFusion?

【问题讨论】:

  • 您好,欢迎来到本站。似乎这个问题更多是关于 ColdFusion 而不是 SQL Server,所以它可能更适合 StackOverflow

标签: sql-server sql-server-2008 stored-procedures error-handling


【解决方案1】:

对这些错误结果尝试 cfcatch.detail:

我提前道歉。我确实在没有测试/编译的情况下一起破解了这个(但我认为你明白了)和关于如何处理错误的 CF 文档。看看 cfcatch.detail 带来了什么:

cftry>
  <cfstoredproc procedure="InsertRecord" datasource="#dsn#">
        <cfprocparam dbvarname="@Status" value="#trim(arguments.frm_status)#" cfsqltype="cf_sql_bit" />
        <cfprocparam dbvarname="@Code" value="#trim(arguments.frm_code)#" cfsqltype="cf_sql_char" maxlength="2" null="#!len(trim(arguments.frm_code))#" />
        <cfprocparam dbvarname="@Name" value="#trim(arguments.frm_name)#" cfsqltype="cf_sql_varchar" maxlength="50" null="#!len(trim(arguments.frm_name))#" />
        <cfprocparam dbvarname="@ActionID" value="#trim(SESSION.UserID)#" cfsqltype="cf_sql_idstamp" maxlength="50" null="#!len(trim(SESSION.UserID))#" />
        <cfprocresult name="Result"/>
    </cfstoredproc>

    <cfset local.fnResults = {status : "200", RecID : Result.RecID}>

<cfcatch type="database">
   <cfoutput>
   <p><b>database error</b><br />
   <ul>
   <li><b>message:</b> #cfcatch.message#
   <li><b>native error code:</b> #cfcatch.nativeerrorcode#
   <li><b>sqlstate:</b> #cfcatch.sqlstate#
   <li><b>detail:</b> #cfcatch.detail#
   </ul>
   </cfoutput>
</cfcatch>
</cftry>

【讨论】:

  • 我不使用 ColdFusion 也没有办法测试,但我猜这需要 O.P. 将 CATCH 块中的 SELECT 替换为 RAISERROR,否则将被视为正常结果集,而不是可捕获的异常。
猜你喜欢
  • 1970-01-01
  • 2012-05-18
  • 1970-01-01
  • 2015-07-07
  • 2011-02-11
  • 2019-01-30
  • 1970-01-01
  • 2016-02-01
  • 1970-01-01
相关资源
最近更新 更多