Answers:
您可以CREATE Function
在脚本开头DROP Function
附近和结尾附近进行调用。
您可以创建临时存储过程,例如:
create procedure #mytemp as
begin
select getdate() into #mytemptable;
end
在SQL脚本中,但不起作用。您可以将proc的结果存储在临时表中,然后稍后在脚本中使用该信息..
BEGIN
关键字并将END
关键字替换为时,我可以从您的示例存储过程中获取结果GO
。
通用表表达式使您可以定义本质上仅在选择,插入,更新和删除语句范围内有效的视图。根据您需要执行的操作,它们可能会非常有用。
我知道我可能会因为建议使用动态SQL而受到批评,但是有时这是一个很好的解决方案。在考虑这一点之前,只需确保您了解安全隐患。
DECLARE @add_a_b_func nvarchar(4000) = N'SELECT @c = @a + @b;';
DECLARE @add_a_b_parm nvarchar(500) = N'@a int, @b int, @c int OUTPUT';
DECLARE @result int;
EXEC sp_executesql @add_a_b_func, @add_a_b_parm, 2, 3, @c = @result OUTPUT;
PRINT CONVERT(varchar, @result); -- prints '5'
在脚本中,您有更多选择,并且可以更好地进行理性分解。查看SQLCMD模式(查询菜单-> SQLCMD模式),特别是:setvar和:r命令。
在存储过程中,您的选择非常有限。您不能直接使用过程主体创建定义函数。您可以做的最好的事情就是使用动态SQL:
create proc DoStuff
as begin
declare @sql nvarchar(max)
/*
define function here, within a string
note the underscore prefix, a good convention for user-defined temporary objects
*/
set @sql = '
create function dbo._object_name_twopart (@object_id int)
returns nvarchar(517) as
begin
return
quotename(object_schema_name(@object_id))+N''.''+
quotename(object_name(@object_id))
end
'
/*
create the function by executing the string, with a conditional object drop upfront
*/
if object_id('dbo._object_name_twopart') is not null drop function _object_name_twopart
exec (@sql)
/*
use the function in a query
*/
select object_id, dbo._object_name_twopart(object_id)
from sys.objects
where type = 'U'
/*
clean up
*/
drop function _object_name_twopart
end
go
如果存在这样的情况,则这近似于全局临时功能。其他用户仍然可以看到它。您可以附加连接的@@ SPID来唯一化名称,但这将要求该过程的其余部分也使用动态SQL。
以下是我过去用来满足MS SQL中标量UDF需求的内容:
IF OBJECT_ID('tempdb..##fn_Divide') IS NOT NULL DROP PROCEDURE ##fn_Divide
GO
CREATE PROCEDURE ##fn_Divide (@Numerator Real, @Denominator Real) AS
BEGIN
SELECT Division =
CASE WHEN @Denominator != 0 AND @Denominator is NOT NULL AND @Numerator != 0 AND @Numerator is NOT NULL THEN
@Numerator / @Denominator
ELSE
0
END
RETURN
END
GO
Exec ##fn_Divide 6,4
这种对PROCEDURE使用全局变量的方法不仅使您可以在脚本中使用功能,而且可以在Dynamic SQL需求中使用该功能。