sql-server - 使用存储过程中的更新语句发出测试错误处理
问题描述
我无法理解为什么代码不起作用。表中有数据vendorproducts
,但是执行后没有检索到数据,并且在我传入时也没有打印错误@vendor=1
ALTER PROCEDURE HW5UD1
@vendor VARCHAR(64),
@Perct DECIMAL(3,2)
AS
BEGIN TRANSACTION
BEGIN TRY
UPDATE VendorProducts
SET paidPrice = paidPrice * (1 + @perct)
WHERE vendor = @vendor
END TRY
BEGIN CATCH
ROLLBACK TRANSACTION
PRINT 'Error occurred while trying to update vendor products table'
RETURN -11001
END CATCH
COMMIT TRANSACTION
SELECT *
FROM VendorProducts
WHERE vendor = @vendor
RETURN 0
解决方案
评论太长了,让我们开始吧。首先,学会提出聪明的问题。您需要多长时间才能显示任何错误消息?您发布了完整的消息还是缩写版本?
ALTER PROCEDURE HW5UD1
重来。这个名字没用。任何阅读您的代码(或调用此过程的代码)的人都应该通过阅读该名称来了解您的过程的作用。
让我们看看你如何调用这个过程。您首先说您使用“@vendor=1”调用此过程。稍后您说“供应商意味着像 DVDemporium 这样的供应商名称”。这里似乎有些错误和不一致。从模式的角度来看,您应该有一个从 VendorProducts 到 Vendors 的外键 (FK)。你?你甚至有供应商表吗?FK 列是 varchar 还是 numeric?我希望是数字,因为您传递了一个值 1。
接下来,您的过程包含一个 DML 语句。单个语句(更新 - 在这种情况下)是原子的,并且将成功或不成功。没有必要进行交易。如果在调用此过程之前启动了事务,则您现在已经嵌套了一个事务,没有任何特殊原因。更糟糕的是,您捕获任何错误,然后在抛出您自己的错误时隐藏 TRUE 错误。您只是通过隐藏使调试任何实际错误变得不可能。tsql 中的错误处理很复杂 - 我建议您阅读Erland 的讨论。
在您的 CATCH 子句中,您使用 print。不——不要。不要尝试使用 print 从过程(或触发器)提供“输出”。这些以大多数调用者不期望也不会处理的方式返回给调用者(完全或按照开发人员的意图)。他们只是产生额外的工作。它可用于调试目的,但不应出现在生产代码中。因为你抛出一个错误,调用者隐含地知道“发生错误......” - 你的打印消息没有添加任何有用的东西。
该过程中的最后一条语句只是从您尝试更新的表中选择行。为什么?如果呼叫者在呼叫时拥有所有这些信息,那么这只会产生额外的“工作”。如果调用者没有,那么您为什么假设调用者想要或需要此信息。一般来说,你的程序应该做一件“事情”。只需更新行。
所以也许这一切都是学习的练习。不幸的是,人们倾向于提供工作代码而没有太多解释。当然,您可以直接复制并上交成绩。但是你不会学到很多东西(如果有的话),这是不幸的。如果没有理解和学习,您将无法发展成为有效开发人员所需的技能。
最后,还有很多关于 tsql 编码最佳实践的讨论。这些你应该阅读并开始实施。
推荐阅读
- javascript - 如何解决 PHP 网站测试中的每个 AMP 错误
- javascript - 我正在做的 Three.js 项目,相机移动很奇怪
- segmentation-fault - 安装不匹配的 glibc 版本后如何恢复损坏的 Ubuntu?
- xamarin.forms - 是否可以使用 Uno 平台将 AdMob 集成到 Android 应用程序中
- scala - 在 scala 中使用 s3 路径中的空格字符执行 cmd
- xmpp - 如何在 ejabberd 中撤回消息?
- python - 如何在python中获取特定文件的路径
- android - 电话交换机如何工作?
- dojo - 更新存储元素在网格中添加行而不删除旧版本
- jquery - 单击 jQuery 播放/暂停多个视频