我可以在脚本或存储过程中创建一次性使用函数吗?

Mar*_*ter 98 sql t-sql sql-server scripting sql-server-2005

在SQL Server 2005中,是否存在在SQL脚本或存储过程中声明的一次性使用或本地函数的概念?我想在我正在编写的脚本中抽象出一些复杂性,但它需要能够声明一个函数.

只是好奇.

Ron*_*age 81

您可以创建临时存储过程,如:

create procedure #mytemp as
begin
   select getdate() into #mytemptable;
end
Run Code Online (Sandbox Code Playgroud)

在SQL脚本中,但不是函数.你可以让proc将它的结果存储在临时表中,然后在脚本中使用该信息.

  • 这应该是答案.如果只是临时连接(单个#),这是真正的单一用途,并且具有绕过sql用户限制的好处. (6认同)
  • 当我删除“BEGIN”关键字并将“END”关键字替换为“GO”时,我可以从示例存储过程中获取结果。 (2认同)

Joe*_*orn 63

您可以CREATE Function在脚本开头DROP Function附近和结尾附近拨打电话.

  • @JoelCoehoorn:这仍然需要写权限. (9认同)
  • @chocojosh,如果你将它包装在一个事务中,那应该没问题.如果事务发生爆炸,该函数不应该在数据库中. (6认同)
  • 我打算这样说.小心你的脚本完成; 如果它中止,你仍然会在数据库中有这个功能. (5认同)
  • 您可以在每次运行之前执行IF EXISTS检查,如果找到任何内容则删除. (5认同)
  • 请注意,这在函数内部不起作用 - 不允许在函数内部使用临时函数.请参阅:https://technet.microsoft.com/en-us/library/ms191320.aspx#Restrictions (2认同)

Wel*_*bog 24

通用表表达式允许您定义基本上仅在select,insert,update和delete语句范围内的视图.根据您的需要,它们非常有用.

  • 我认为这个答案,以及它是正确答案的断言,错过了问题是寻找一个临时功能,而不是临时表.除非我遗漏了某些东西(并非罕见),否则CTE与临时表相当. (14认同)
  • 取决于你想要做什么.我发现了这个问题,因为我正在编写一个数据播种器,我不想重复10行MERGE INTO 30次.我不关心线程安全,CTE不适合我. (10认同)
  • 函数可以接受参数,而CTE则不能. (8认同)
  • 这应该被接受为正确的答案.接受的答案不是线程安全的. (5认同)
  • CTE和临时存储过程之间有很多区别(这是IMO的正确答案)。对于初学者,CTE仅针对单个语句存在,而临时变量可以在整个脚本中使用。其他差异包括:(1)CTE无法容纳SP可以容纳的相同逻辑;(2)CTE无法接受变量。CTE只是语法糖,它使您可以更轻松地构建嵌套表表达式以在语句中使用。即使这样,如果您不注意警告,它们也会对性能造成危险。 (3认同)

Tmd*_*ean 11

我知道我可能因为建议动态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'
Run Code Online (Sandbox Code Playgroud)


小智 6

下面是我过去用来满足 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
Run Code Online (Sandbox Code Playgroud)

这种方法使用 PROCEDURE 的全局变量,使您不仅可以在脚本中使用该函数,还可以在动态 SQL 需求中使用该函数。

  • 有人可以告诉我这个答案 /sf/answers/68704401/ 有什么区别吗? (2认同)