Upsert是否违反单一责任原则?

时间:2012-05-15 21:33:02

标签: sql sql-server oop design-patterns stored-procedures

我喜欢使用Upsert存储过程来更新记录(如果存在),如果不存在则插入它们。没有它们,我需要首先找出记录是否存在,然后根据结果调用两个独立的存储过程。

在我创建名为UpdateOrDeleteRow的存储过程之前,我从未真正考虑过这个问题。当我发现自己在名字中包含“或”时,我的SRP蜘蛛感开始了,我意识到这些upotss基本上是相同的。

这是违反SRP的吗?如果是这样,是否可以接受?如果没有,我该怎么办?

我意识到SRP是一个OOP原则,而T-SQL不是OOP语言,但原则的基础似乎也适用于此。

5 个答案:

答案 0 :(得分:4)

还有另一个原则,我更喜欢SRP - DRY。因此,如果您在一个地方调用此序列,您可以考虑单一责任。但是当你多次重复相同的动作序列时,DRY会让我删除重复。

BTW我想一想,您可以在程序/方法名称中避免使用ORUpdateOrInsert操作具有非常好的名称Save。我认为它不会打破SRP。

答案 1 :(得分:3)

我个人认为这个原则并不完全适用于SQL Server。存储过程并不总是只执行一个操作(我认为存储过程等同于一个类的概念是有缺陷的)。我认为将存储过程中的每个语句拆分为自己的存储过程并不合理。你可以对此非常荒谬。

当然,有一种平衡,因为你可能是荒谬的另一种方式。您不希望存储过程有18种不同的方式来指定参数,以便它可以根据组合执行540种不同的操作。

对于UPSERT,我仍然建议单个存储过程对此没问题。如果您希望更好地将其用于单一用途,请将更新/插入更改为单个MERGE。 :-)尽管如此,be very careful with MERGE。{/ p>

答案 2 :(得分:1)

如果您已经有独立执行Update或Delete操作的过程,希望通过日志记录进行审计,您可以让upsert proc单独调用它们。这样只有那些触发器才能完成有助于保持可管理性的工作,即使它们是从多个位置调用的。

答案 3 :(得分:1)

单一责任原则说,一个对象应该只有一个改变的理由。 Upsert存储过程应该更改的唯一原因是表结构是否更改。因此,我认为您可以创建upsert存储过程。

答案 4 :(得分:1)

我不同意委托人应该适用于这种情况,因为它会在你的代码隐藏中产生一些冗余代码。

首先让我们检查一下你的UPSERT做了什么,它会检查数据是否存在然后基于它执行INSERT或UPDATE。

在代码隐藏中执行此操作时,您必须对数据库进行2次调用,具体取决于应用程序的结构,这也可能意味着打开和关闭两个连接。

因此,您在codebehind中有3个方法(一个用于执行每个proc),然后是一个方法来调用每个方法并执行逻辑来决定是否需要插入或更新。

您的数据库中还有3个单独的存储过程来执行每个操作。

对我而言,这似乎是结构错误的代码,因为您将相同的参数传递给插入/更新过程,就像你对upsert一样,因此在一个地方完成这一操作是有意义的。

通过使用UPSERT,您有1个存储过程,只需要一个连接,一个方法可以从代码隐藏中调用。我认为这会使代码更好,更清晰。