我有2个存储过程,其中第一个在事务中调用第二个。第二个过程绝对不能直接调用,而只能在其父内部调用。
当前,要检查是否存在这种情况,我将在第二个过程中执行以下操作:
DECLARE @inTran bit;
IF @@TRANCOUNT > 0
SET @inTran= 0
ELSE
SET @inTran= 1
这是正确的吗?有更好的方法吗?
答案 0 :(得分:2)
如果您只是在寻找一种随意的方式来防止proc自身的无意执行。您还可以检查@@NESTLEVEL
-如果从另一个proc调用,则至少为2
。
CREATE PROCEDURE Child
AS
IF @@NESTLEVEL < 2 OR @@TRANCOUNT = 0
THROW 50000, 'Child proc should be called from Parent', 1;
或者您可以让父proc在子proc中设置一个SESSION_CONTEXT()
读取的值。
但是,所有这些都不能防止proc未能按确定的规避某人的意图运行。他们只是防止意外的误用。
答案 1 :(得分:0)
没有可靠的方法来执行此操作。选中@@ trancount只会为您提供信息,无论您是否正在进行交易,而且有人可以这样做:
BEGIN TRAN
EXECUTE nested_proc_directly
在这种情况下,proc中的事务计数b将大于0。正如其他人所说,您不能调用堆栈。所以,对不起。
答案 2 :(得分:0)
我在这里在两行之间进行了一点阅读,并猜测实际的问题是如何防止Procedure2
以外的任何进程运行Procedure1
。
如果必须尽可能将其完全锁定,请创建一个专用的服务帐户来运行这些过程或其相关的工作,然后仅授予EXECUTE
的{{1}}权限}到该专用帐户。
如果“完全锁定”足够好,请仅将Procedure2
上的EXECUTE
权限授予您已在生产中运行作业的服务帐户。至少这样可以防止流浪用户将它发射出去。
另一种想法是创建一个包含两个Procedure2
的SSIS包,第一个包含Execute SQL Tasks
中的所有代码,第二个包含Procedure1
中的所有代码,然后删除proc并运行程序包。不过,我不关心将代码嵌入程序包中,因为维护很烦人。
答案 3 :(得分:0)
为此,您可以使用@@PROCID。唯一的问题是您需要通过输入传递参数。
Traceback (most recent call last):
File "test_code.py", line 66, in <module>
testspark = spark.read.json(bucket_path + blob.name).cache()
File "/home/anaconda3/envs/py37base/lib/python3.6/site-packages/pyspark/sql/readwriter.py", line 274, in json
return self._df(self._jreader.json(self._spark._sc._jvm.PythonUtils.toSeq(path)))
File "/home/anaconda3/envs/py37base/lib/python3.6/site-packages/py4j/java_gateway.py", line 1257, in __call__
answer, self.gateway_client, self.target_id, self.name)
File "/home/anaconda3/envs/py37base/lib/python3.6/site-packages/pyspark/sql/utils.py", line 63, in deco
return f(*a, **kw)
File "/home/anaconda3/envs/py37base/lib/python3.6/site-packages/py4j/protocol.py", line 328, in get_return_value
format(target_id, ".", name), value)
py4j.protocol.Py4JJavaError: An error occurred while calling o51.json.
: java.io.IOException: No FileSystem for scheme: gs
输出
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