如果在另一个存储过程中调用了一个存储过程,是否有可能获得?
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" 足够好,请仅向您在生产环境中 运行 拥有作业的服务帐户授予对 Procedure2
的 EXECUTE
权限。至少这可以防止流浪用户随意解雇它。
另一个想法是创建一个包含两个 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 不是 运行 但决心规避限制的人的意图。他们只会防止意外误用。
我有 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" 足够好,请仅向您在生产环境中 运行 拥有作业的服务帐户授予对 Procedure2
的 EXECUTE
权限。至少这可以防止流浪用户随意解雇它。
另一个想法是创建一个包含两个 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 不是 运行 但决心规避限制的人的意图。他们只会防止意外误用。