假设我想创建一个sql脚本并执行以下操作:
DECLARE @SomeVariable int SET @SomeVariable = 'VALUE' FROM someTable --do stuff with @SomeVariable GO CREATE PROCEDURE myProcedure ( @MyParameter ) AS SET NOCOUNT ON --Do something --Do something using @SomeVariable SET NOCOUNT OFF RETURN 0 GO
我不能,因为@SomeVariable与他所属的批次一起死亡,而myProcedure需要它自己的批次。显然,我可以创建一个#temp表并在其中填充所需的任何值,但随后我必须从中选择- 添加代码,尽管琐碎,但会损害可读性,并且当我需要的只是一个全局变量时似乎很愚蠢。有没有更好的办法?
要痛苦地清除。我知道SQL Server具有称为“表”的“全局变量”-我在上一段中提到使用#table是一种可能的解决方案,就像使用实际的永久表一样。我在这里寻找的可能更多是我可以在给定脚本中的任何地方使用的全局常量,而不是全局变量- 因此我们都可以停止为全局变量的弊端而烦恼。
尚不清楚为什么在两个批次的示例集中,存储的proc依赖于您的全局变量。我看到了两种主要可能性:SP在创建时就依赖于全局(即代码生成- 情况1),或者SP在运行时对全局具有依赖性(即您必须在参数化-情况2之间进行选择),或者自我配置-Case3)。
对于运行时依赖关系,是从SP外部的某个位置获取并作为参数传递还是直接在SP内部传递,这是基本的设计决策。选择何时传递数据作为参数以及何时从表中提取数据并不是一门科学,而是全部取决于系统中所有实际的使用情况。
情况1-代码生成:
DECLARE @SomeVariable int SET @SomeVariable = 'VALUE' FROM someTable --do stuff with @SomeVariable GO DECLARE @sp as varchar(MAX) SET @sp = ' CREATE PROCEDURE myProcedure -- I would actually name this myProcedure_ + CONVERT(varchar, @SomeVariable), since each proc generated might function differently ( @MyParameter ) AS SET NOCOUNT ON DECLARE @SomeVariable AS int -- This is going to be an initialized local copy of the global at time of SP creation SET @SomeVariable = ' + CONVERT(varchar, @SomeVariable) + ' --Do something --Do something using @SomeVariable SET NOCOUNT OFF RETURN 0 ' EXEC(@sp) -- create the procedure dynamically Executing the producedure normally as EXEC myProcedure or EXEC myProcedure_1, etc.
情况2-参数化:
DECLARE @SomeVariable int SET @SomeVariable = 'VALUE' FROM someTable --do stuff with @SomeVariable GO CREATE PROCEDURE myProcedure ( @MyParameter ,@SomeVariable int ) AS SET NOCOUNT ON --Do something --Do something using @SomeVariable SET NOCOUNT OFF RETURN 0 GO
现在,无论何时myProcedure调用,都必须始终将其传递给参数@SomeVariable。当您定期调用具有不同参数化的同一SP时,建议使用此方法
myProcedure
@SomeVariable
情况3-配置:
DECLARE @SomeVariable int SET @SomeVariable = 'VALUE' FROM someTable --do stuff with @SomeVariable GO CREATE PROCEDURE myProcedure ( @MyParameter ) AS SET NOCOUNT ON --Do something DECLARE @SomeVariable int SET @SomeVariable = 'VALUE' FROM someTable SET NOCOUNT OFF RETURN 0 GO
现在,无论何时执行EXEC myProcedure,都需要确保已在表中设置了配置。对于缓慢更改的配置案例,建议使用此方案。在这种情况下,您可以将@SomeVariable初始化包装在标量值的UDF中,这样,每次在不同的SP中使用相同的配置时,它们都将通过同一UDF进行调用,从而使您可以自由更改配置表约定(不必还是不向您的用户授予对表的SELECT权限,对吗?)并且,如果UDF需要根据用户或类似用户开始更改,那么您现在有了一个控制点,该控制点强制执行一致性,权限和接口调用约定:
DECLARE @SomeVariable int SET @SomeVariable = dbo.udf_Global(username, session, etc.) --do stuff with @SomeVariable GO CREATE PROCEDURE myProcedure ( @MyParameter ) AS SET NOCOUNT ON --Do something DECLARE @SomeVariable int SET @SomeVariable = dbo.udf_Global(username, session, etc.) SET NOCOUNT OFF RETURN 0 GO