spe*_*741 2 stored-procedures update
我正在着手一个大型项目,并且对存储过程有一般的询问。
假设我有一张User
桌子。
UserKey IDENTITY NOT NULL PRIMARY KEY
FirstName nvarchar(50)NOT NULL
LastName nvarchar(50) NOT NULL
Email nvarchar(50) NOT NULL
Birthdate date NULL
EffectiveFrom datetimeoffset NOT NULL
EffectiveThru datetimeoffset NULL
Run Code Online (Sandbox Code Playgroud)
实际上,这里还有更多的领域,但为了简洁起见,我已经将其简化为基础知识。
现在,我面临着创建存储过程以允许此表的基本 CRUD 功能的问题。
插入过程非常简单。
usp_INSERT_User
:
CREATE PROCEDURE [dbo].[usp_INSERT_User]
(
--@UserKey BIGINT,
@FirstName NVARCHAR(50),
@LastName NVARCHAR(50),
@Email NVARCHAR(50),
@BirthDate DATE = NULL,
@EffectiveFromDtTm DATETIMEOFFSET(7),
@EffectiveThruDtTm DATETIMEOFFSET(7) = NULL,
)
Run Code Online (Sandbox Code Playgroud)
我的主要问题是我应该如何编写更新程序。
由于可以有非常细粒度的更新,我是否应该为每个细粒度更新创建一个更新存储过程?
例如,假设我只想在为用户处理完经过验证的电子邮件更新后更新用户的电子邮件,我会编写一个带有一个参数的 sproc 吗?
usp_UPDATE_UserEmail @NewEmail
如果用户更新了他们的个人资料,我可以编写一个 sproc,如:
usp_UPDATE_User @UserKey, @FirstName, @LastName, @Email, @Birthdate
因此,为了涵盖我最常见的更新操作,我最终可能会使用一些 sproc 来涵盖更新User
表的用例。显然,表越大和/或业务需求的数量越多,与为特定表编写的更新 sproc 的数量直接相关。这让我想到了大量 sproc 的可维护性。
昨天,我去了兔子洞
“哦,为什么我不只写一个最终所有的更新 sproc,它可以接受我想通过 XML 参数更新的任何参数”
幸运的是,在不使用动态 sql 的情况下,我能够创建那个怪物。它有效。
然后我决定测试我喜欢的 xml sproc 和具有非常相似更新的常规更新 sproc(具有多个参数)之间的速度。
因此,我创建了一个包含 1200 万条记录的模拟用户表并测试了这两种方法。不出所料,XML 方法平均花费的时间比 vanilla 更新 sproc 长 7 倍。
将参数序列化为 XML 的线路的另一端还有额外的开销,这可能会与大型更新批次有关。
现在,我说所有这些都是为了总结并询问您的经验中最常(如果有的话)看到哪种类型的方法?是最常见的做法有颗粒状的存储过程像usp_UPDATE_Field1
/ usp_UPDATE_Field2
/ usp_UPDATE_Field3&4
OR usp_UPDATE_whateveryouwant
我喜欢黄金 sproc 的简单性,它可以接受您想要传递的参数数量并相应地更新它们,但也存在性能缺陷。
提供更多上下文:运行 SQL Server 2019。我对这个东西也很陌生。
谢谢你的帮助!
存储过程是数据库的编程 API,是您调用以改变系统状态的方法。因此,我更喜欢让 SP 名称反映所需的业务结果而不是实现 - change_of_address 而不是 update_customer。每个 SP 都有参数来执行该业务更改,而没有其他参数。每个人都做一件事,而且做得很好。
如果业务支持两个都更新公共列的流程,那么就这样吧。该列是每个 SP 的输入。假设有一个基于网络的“更改配置文件”和一个仅限移动设备的“注册新手机”。他们都写信给 customer.phone_number。我将为每个业务目的拥有单独的 SP。
拥有许多小的、紧密集中的存储过程没有可衡量的开销。对数据类型的更改在下一次重新编译时自动进行。对列名的更改是简单的搜索和替换。SSMS 的内置依赖性分析也可以提供帮助。如果您使用镜像列的局部变量使用列的名称,例如 customer_name 被读入@old_customer_name。