T-SQL - 具有默认参数的函数

nir*_*mus 145 t-sql function default-parameters

我有这个脚本:

CREATE FUNCTION dbo.CheckIfSFExists(@param1 INT, @param2 BIT = 1 )
RETURNS BIT
AS
BEGIN
    IF EXISTS ( bla bla bla )
        RETURN 1;
    RETURN 0;
END
GO
Run Code Online (Sandbox Code Playgroud)

我想以这种方式在一个过程中使用它:

IF dbo.CheckIfSFExists( 23 ) = 0
    SET @retValue = 'bla bla bla';
Run Code Online (Sandbox Code Playgroud)

但我得到错误:

为程序或函数dbo.CheckIfSFExists提供的参数数量不足.

为什么不起作用?

SQL*_*ace 218

你必须像这样称呼它

SELECT dbo.CheckIfSFExists(23, default)
Run Code Online (Sandbox Code Playgroud)

来自Technet:

当函数的参数具有默认值时,必须在调用函数时指定关键字DEFAULT以便检索默认值.此行为与在存储过程中使用具有默认值的参数不同,其中省略参数也意味着默认值.此行为的一个例外是使用EXECUTE语句调用标量函数时.使用EXECUTE时,不需要DEFAULT关键字.

  • 看到这一点我很沮丧.我没有在这里获得"默认"概念的优势......我现在需要去改变所有的地方. (72认同)
  • 因为我们不允许覆盖,并且"默认"因此具有有限的可用性,所以通常最好的方法是使用额外参数创建具有后缀的新扩展版本(比如说CheckIfSFExistsEX here),并将原始函数更改为just使用"default"参数调用扩展版本.这样所有现有代码都可以工作,而且只有一个地方可以维护. (7认同)
  • @Lijo,你仍然可以在每次通话时不重复你的具体默认值. (6认同)
  • 呃微软。如果您“需要”向它传递一个值,那么它实际上并不是一个***可选***参数。我希望他们可以在未来的版本中改变这一点。 (4认同)
  • @Ben 同意,但在他们的辩护中,他们没有说这是一个可选参数。它是一个具有默认值的参数。它的唯一好处是使函数调用者不必知道将参数设置为什么值。我想他们认为调用者确认参数的存在很重要 - 即选择退出。但我也更喜欢一个可选参数。 (4认同)

小智 38

您可以通过三种方式调用它 - 使用参数,使用DEFAULT和EXECUTE

SET NOCOUNT ON;

DECLARE
@Table  SYSNAME = 'YourTable',
@Schema SYSNAME = 'dbo',
@Rows   INT;

SELECT dbo.TableRowCount( @Table, @Schema )

SELECT dbo.TableRowCount( @Table, DEFAULT )

EXECUTE @Rows = dbo.TableRowCount @Table

SELECT @Rows
Run Code Online (Sandbox Code Playgroud)

  • 为什么在select中需要`DEFAULT`关键字,但在执行时可以省略?这很糟糕:/希望有一天这个问题会得到解决. (5认同)
  • @GustavoPinsard 允许这样做的一个很好的理由是当您向函数添加新参数时。如果您不必指定默认值,该函数可以继续在现有应用程序中工作。如果您现在想这样做,则需要使用额外参数创建一个新函数,并从原始(现已弃用)函数中调用它。这是有一定价值的,但在我看来,它会在数据库中产生额外的噪音。新函数的命名通常比原来的函数更糟糕,因为函数重载也是不可能的。 (3认同)
  • @Misiu,这不是需要“修复”的东西。这是设计使然。我阅读了很多替代方案来实现“理想”目标,即能够简单地调用函数而不指定每个参数,但我没有看到为什么需要这样做的明确解释。代码应该清晰,实现这一点的一个策略是要求编码人员始终意识到“嘿,您正在调用一个确实有这个参数和其他参数的函数,这些参数恰好有默认值。不要忘记默认值可能会更改”。所以,在我看来,这是一件好事“坏事”。 (2认同)

Cur*_*urt 16

使用用户定义的函数,您必须声明每个参数,即使它们具有默认值.

以下将成功执行:

IF dbo.CheckIfSFExists( 23, default ) = 0
    SET @retValue = 'bla bla bla;
Run Code Online (Sandbox Code Playgroud)