当尝试在存储过程中验证用户提供的GUID时,使用了一种简单的方法;将用户输入作为CHAR(36),然后在TRY CATCH中明确地将其作为UNIQUEIDENTIFIER进行CAST。然后CATCH使用RAISERROR使用自定义错误描述来消除错误。
手动运行存储过程,一切都按预期执行,并引发错误。
创建一个tSQLt测试来调用单元(具有GUID验证的过程)并处理输出的错误并与预期的错误进行比较,并且因事务错误而不断失败; tSQLt检测到错误并在tSQLt框架内处理。
这向我表明,tSQL处理不同CAST到不同数据类型的严重性,并且它阻止了存储过程中的TRY / CATCH来处理它。与嵌套过程非常相似,有时会忽略子过程中的TRY / CATCH并冒泡到父过程;例如,如果孩子处理。引用一个不存在的表。
有没有人有类似的问题?只是简单地验证我目前的思路。
我已经删除了测试,并且正在其他地方进行测试,但这导致了我的数据库单元测试中的“漏洞”。
最后,我想我应该提一下,我知道我可以对提供的CHAR参数执行不同的验证,而不是CAST,并以这种方式引发错误,但这是一个tSQLt查询而不是tSQL查询。 / p>
修改
代码示例:
@sGUID是一个CHAR(36),是传递给过程的参数。
BEGIN TRY
SELECT CAST(@sGUID AS UNIQUEIDENTIFIER)
END TRY
BEGIN CATCH
RAISERROR('Invalid GUID format',16,1)
END CATCH
SELECT行永远不会触发CATCH tSQLt似乎在事先干预并抛出ROLLBACK事务错误。
答案 0 :(得分:0)
当您调用RAISEERROR()时,您将终止正在运行tSQLt的事务 - >因此你看到了交易错误。
为了进行单元测试,可以考虑使用一个选项,即通过调用仅包含RAISERROR()的自定义存储过程来替换RAISEERROR()语句。这样,您可以单独对该存储过程进行单元测试。
BEGIN TRY
SELECT CAST(@sGUID AS UNIQUEIDENTIFIER)
END TRY
BEGIN CATCH
EXEC dbo.customprocedure
--RAISERROR('Invalid GUID format',16,1)
END CATCH