如果在另一个存储过程中调用了一个存储过程,是否有可能获得?

Is it possible to get if a stored procedure is called within another stored procedure?

我有 2 个存储过程,其中第一个在事务中调用第二个。不应直接调用第二个过程,而只能从其父过程中调用。

目前,为了检查是否属于这种情况,我在第二个过程中执行了以下操作:

DECLARE @inTran bit;
IF @@TRANCOUNT > 0
    SET @inTran= 0
ELSE
    SET @inTran= 1

这是正确的吗?有更好的方法吗?

没有可靠的方法可以做到这一点。检查@@trancount 只会为您提供您是否在交易中的信息,有人可以这样做:

BEGIN TRAN
EXECUTE nested_proc_directly

在这种情况下,proc 中的 tran 计数将大于 0。正如其他人所说,您不能调用堆栈。所以,抱歉。

我稍微读了一下这里的字里行间,并猜测实际问题是如何防止 Procedure2 被任何进程 运行 除了来自 [=11= 的调用].

如果这必须尽可能接近完全锁定,请为 运行 这些过程或其相关作业创建一个专用服务帐户,然后仅授予 EXECUTE Procedure2 对该专用帐户的权限。

如果 "pretty locked down" 足够好,请仅向您在生产环境中 运行 拥有作业的服务帐户授予对 Procedure2EXECUTE 权限。至少这可以防止流浪用户随意解雇它。

另一个想法是创建一个包含两个 Execute SQL Tasks 的 SSIS 包,第一个包含 Procedure1 中的所有代码,第二个包含 Procedure2 中的所有代码,然后取消 procs 和 运行 包。不过,我不喜欢在包中嵌入代码,因为维护很烦人。

您可以为此使用 @@PROCID。唯一的问题是你需要通过输入传递参数。

CREATE PROCEDURE usp_Test1(@id As int)
AS 
PRINT @id
PRINT OBJECT_NAME(@id)
GO 

CREATE PROCEDURE usp_Test2
AS
EXEC usp_Test1 @@PROCID
GO

EXEC usp_Test2
GO

输出

1054730910
usp_Test2

如果您只是在寻找一种随意的方式来防止 proc 自己无意中执行。您还可以检查 @@NESTLEVEL - 如果从另一个过程调用,这将至少是 2

CREATE PROCEDURE Child
AS
    IF @@NESTLEVEL < 2 OR @@TRANCOUNT = 0
    THROW 50000, 'Child proc should be called from Parent', 1;

或者您可以让父进程在子进程中设置一个由 SESSION_CONTEXT() 读取的值。

None 这些将防止 proc 不是 运行 但决心规避限制的人的意图。他们只会防止意外误用。