如何处理 ColdFusion 存储过程结果中的错误?
How to handle errors in ColdFusion stored procedure results?
我使用 ColdFusion 调用存储过程来插入或更新用户数据。这两项交易分为两个程序。我的 SQL 代码应该 return 行计数 1 或 0 取决于事务是否成功。如果交易失败,我想知道在这种情况下处理错误的最佳方法是什么? cfstoredproc
都包含在 try/catch 块中,但如果 SQL 过程中发生错误,结果集中的 Count
变量将 return 0 和 try/catch 不会从程序中注册错误 return。这是我的代码示例:
<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>
上面的代码 returns Count column/variable 正如我已经从结果集中提到的那样。如果流程成功执行,用户将收到消息通知。如果出现问题,我想向他们发送一条消息,该消息位于我的 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 的角度来看,存储过程已正确执行。
当存储过程没有 return 记录集时,我倾向于对所有对存储过程的调用使用标准消息包。将两个局部变量添加到您的过程并根据需要更新:
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
而且return这些值在CATCH
之后,这样proc总是return一个状态。
SELECT
@SUCCESS as success,
@MSG as message
这将为您提供一条用户友好的消息,以及可以根据需要记录的实际 SQL 错误(当它发生时)。
我使用 ColdFusion 调用存储过程来插入或更新用户数据。这两项交易分为两个程序。我的 SQL 代码应该 return 行计数 1 或 0 取决于事务是否成功。如果交易失败,我想知道在这种情况下处理错误的最佳方法是什么? cfstoredproc
都包含在 try/catch 块中,但如果 SQL 过程中发生错误,结果集中的 Count
变量将 return 0 和 try/catch 不会从程序中注册错误 return。这是我的代码示例:
<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>
上面的代码 returns Count column/variable 正如我已经从结果集中提到的那样。如果流程成功执行,用户将收到消息通知。如果出现问题,我想向他们发送一条消息,该消息位于我的 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 的角度来看,存储过程已正确执行。
当存储过程没有 return 记录集时,我倾向于对所有对存储过程的调用使用标准消息包。将两个局部变量添加到您的过程并根据需要更新:
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
而且return这些值在CATCH
之后,这样proc总是return一个状态。
SELECT
@SUCCESS as success,
@MSG as message
这将为您提供一条用户友好的消息,以及可以根据需要记录的实际 SQL 错误(当它发生时)。