sql-server-2008 - 如何处理ColdFusion存储过程结果中的错误?

标签 sql-server-2008 error-handling coldfusion coldfusion-2016 cfstoredproc

我使用ColdFusion调用存储过程来插入或更新用户数据。这两个事务通过两个过程分开。我的SQL代码应该返回行计数1或0,这取决于事务是否成功。如果交易失败,我想知道在那种情况下处理错误的最佳方法是什么?两个cfstoredproc都包装在try/catch块中,但是如果SQL过程中发生错误,结果集中的Count变量将返回0,而try/catch不会注册过程返回的错误。这是我的代码示例:

<cftry>
    <cfif trim(arguments.process) EQ "Insert">
        <cfstoredproc procedure="InsertRec" datasource="#dsn#">
            <cfprocparam dbvarname="@Status" value="#trim(arguments.status)#" cfsqltype="cf_sql_bit" />
            <cfprocparam dbvarname="@Code" value="#trim(arguments.frmcode)#" cfsqltype="cf_sql_char" maxlength="2" null="#!len(trim(arguments.code))#" />
            <cfprocparam dbvarname="@Name" value="#trim(arguments.name)#" cfsqltype="cf_sql_varchar" maxlength="50" null="#!len(trim(arguments.name))#" />
            <cfprocresult name="Result"/>
        </cfstoredproc>
    <cfelse>
        <cfstoredproc procedure="UpdateRec" datasource="#dsn#">
            <cfprocparam dbvarname="@Status" value="#trim(arguments._status)#" cfsqltype="cf_sql_bit" />
            <cfprocparam dbvarname="@Code" value="#trim(arguments.code)#" cfsqltype="cf_sql_char" maxlength="2" null="#!len(trim(arguments.code))#" />
            <cfprocparam dbvarname="@Name" value="#trim(arguments.name)#" cfsqltype="cf_sql_varchar" maxlength="50" null="#!len(trim(arguments.name))#" />
            <cfprocresult name="Result"/>
        </cfstoredproc>
    </cfif>

    <cfset local.fnResults = {
         status : "200", 
         message : "Record successully saved!", 
         recCount : Result.Count
    }>

    <cfcatch type="any">
         <cfset local.fnResults = {
             error : cfcatch, <!--- I use this just for testing purpose. --->
             status : "400",
             message : "Error! Please contact your administrator."
         }>
    </cfcatch>
</cftry>

上面的代码返回Count列/变量,正如我在结果集中提到的那样。如果过程成功执行,将向用户通知该消息。如果出了什么问题,我想向他们发送一条消息,该消息位于catch块中。这是SQL代码:
CREATE PROCEDURE [dbo].[InsertRec] 
    @Status BIT = NULL,
    @Name VARCHAR(50) = NULL,
    @Code CHAR(2) = NULL
AS
    SET NOCOUNT ON
    SET XACT_ABORT ON
    BEGIN TRY
        BEGIN
            INSERT INTO dbo.Books(
                Status,Name,Code
            )
            VALUES(
                @Status,@Name,@Code
            )
            SELECT @@ROWCOUNT AS Count;
        END
    END TRY
    BEGIN CATCH
        SELECT 
            @@ROWCOUNT AS Count, 
            ERROR_PROCEDURE() AS ErrorProcedure,
            ERROR_LINE() AS ErrorLine,
            ERROR_NUMBER() AS ErrorNumber,
            ERROR_MESSAGE() AS ErrorMessage,
            CURRENT_TIMESTAMP AS DateTime
    END CATCH

由于更新过程相同,因此我只显示了插入SQL代码。使用时,如果出现问题,我会看到此消息。当我尝试插入已经故意存在的主键时,这只是一个例子:
COUNT   
0
DATETIME        
2018-08-24 07:00:01.58
ERRORLINE   
16
ERRORMESSAGE    
Violation of PRIMARY KEY constraint 'PK_Books'. Cannot insert duplicate key in object 'dbo.Books'. The duplicate key value is (44).
ERRORNUMBER 
2627    
ERRORPROCEDURE
InsertRec

ColdFusion没有捕获此错误。当我使用ColdFusion在结果集中调用存储过程时,是否有办法捕获此错误?

最佳答案

正如@Ageax提到的那样,您正在处理存储过程中的错误,因此从CF的 Angular 来看,存储过程可以正确执行。

当存储过程不返回记录集时,我倾向于对所有存储过程调用使用标准消息包。向您的proc添加两个局部变量,并根据需要进行更新:

DECLARE @SUCCESS BIT = 1;
DECLARE @MSG VARCHAR(50) = 'Some default success message.'

CATCH语句中更新这些值:
BEGIN CATCH
    SET @SUCCESS = 0;
    SET @MSG = 'There was a problem ...';
    SELECT 
        @SUCCESS as success,
        @MSG as message,
        @@ROWCOUNT AS Count, 
        ERROR_PROCEDURE() AS ErrorProcedure,
        ERROR_LINE() AS ErrorLine,
        ERROR_NUMBER() AS ErrorNumber,
        ERROR_MESSAGE() AS ErrorMessage,
        CURRENT_TIMESTAMP AS DateTime
END CATCH

但也要在CATCH之后返回这些值,以便proc始终返回状态。
SELECT 
    @SUCCESS as success,
    @MSG as message

这将为您提供用户友好的消息,以及可以根据需要记录的实际SQL错误(发生时)。

关于sql-server-2008 - 如何处理ColdFusion存储过程结果中的错误?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52004271/

相关文章:

javascript - 捕获头脚本中的js解析错误

coldfusion - 如何使用 cfzip 重命名文件?

error-handling - 检查推送是否成功-angularfire2

javascript - Internet Explorer、ColdFusion 和 Ajax

使用非管理帐户的 ColdFusion 字体管理

xml - 将 (Sql Server) xml 列与 Entity Framework 一起使用

c# - 拆分字符串或 XML 以将 ID 发送到存储过程?

database - SQL 截断数据库?如何截断所有表

sql - 如何从数据库中选择一条记录并在原子查询中对其进行更新

android - 启动android应用时出错