我参与了一个有以下要求的项目:
TableA是父表。每当更新TableA的任何子记录时,TableA中的“LastActivityDate”字段应使用当前的UTC日期进行更新。
现在,我知道有很多方法可以做到这一点。我的帖子并不是关于可以实现的许多不同方式。
我最初建议使用触发器来满足此要求,我们的DBA会因为他们不想在此数据库中使用触发器而将我击倒(我不知道为什么,这对我的问题并不重要)。我最终创建了一个存储过程,其唯一目的是更新TableA.LastActivityDate。然后我编写了TableA的子进程的更新/插入存储过程来调用这个存储过程。因此,例如,子项的更新存储过程将如下所示:
Create Procedure TableB_UPD
(
@TableBId INT
@TableBName VARCHAR(30)
)
AS
BEGIN
UPDATE dbo.TableB
SET TableBName = @TableBName
WHERE
(TableBId = @TableBId)
DECLARE @TableAId INT
SELECT
@TableAId = TableAId
FROM
dbo.TableB
WHERE
(TableBId = @TableBId)
EXEC dbo.TableA_LastActivityDate_UPD @TableAId
END
这是非常简单的代码,我从TableB_UPD存储过程中调用dbo.TableA_LastActivityDate_UPD存储过程。当我们的DBA看到这一点时,他们拒绝在他们的数据库中允许它。他们告诉我,在存储过程中调用存储过程会有很大的性能损失。我一直无法找到任何好的在线文章来支持这个声明(而且DBA也没能给我任何一个)。
我在很多数据库中都看到过这种代码,直到现在才听说过任何性能问题。我的问题是:有人可以解释这类代码的性能问题吗?我也非常感谢对文章的引用。
这是在SQL Server 2005中。
答案 0 :(得分:3)
如有疑问,请查看执行计划和SQL事件探查器,以确保您的过程以最佳方式执行。他们可以告诉你比我们更多的情况。
我能想到的唯一一个涉及嵌套存储过程甚至远程被认为是问题的问题是在带有事务的嵌套存储过程中的错误处理,但是你似乎没有这样做。实际上,我的例子更多的是“正确编写存储过程。”
尽管如此,嵌套存储过程是一个“巨大的性能损失”对我来说是新闻,我肯定找不到支持该声明的任何内容。
答案 1 :(得分:3)
我和@mike在一起,你的代码不应该有任何问题。对我而言,听起来他们听到的东西或曾经看过一些东西,它就变成了法律。相反,向他们证明你的代码是有效的。向他们询问测试实例并让它飞起来。
答案 2 :(得分:2)
嵌套存储过程正常。我们在时间敏感的数据仓库情况下经常使用它们。一旦我们从客户那里接收到procs,我们就会调用procs来调用procs来按月周期格式化所有数据。
以这种方式执行或直接运行procs或将它们作为查询运行不会降低性能 - 我们已经对几乎所有程序进行了广泛的效率测试。
根据您的问题,您可能正在与完全无能的DBA合作。一点知识是危险的。
答案 3 :(得分:1)
您的嵌套过程调用的解决方案没有任何问题。但是为了安抚你的DBA,为什么不在更新表B的过程中写出更新语句来更新LastActivityDate?
我确信一些重复的代码将是您在此数据库中最少的问题
答案 4 :(得分:0)
无论性能如何,我会在一次交易中采用不同的方式,而且更简单:
Create Procedure TableB_UPD
(
@TableBId INT
@TableBName VARCHAR(30)
)
AS
BEGIN
SET XACT_ABORT ON;
BEGIN TRAN;
UPDATE dbo.TableB
SET TableBName = @TableBName
WHERE
(TableBId = @TableBId)
UPDATE dbo.TableA
SET LastActivityDate = CURRENT_TIMESTAMP
WHERE
(TableBId = @TableBId)
COMMIT;
END