为什么不能将GETDATE()用作过程参数的默认值或EXECUTE语句中的值?

时间:2018-12-18 12:19:07

标签: sql-server tsql

请考虑以下存储过程:

CREATE OR ALTER PROCEDURE MySchema.MyProcedure
   @myDateTimeParam DATETIME = GETDATE()
AS
BEGIN
   -- Do something spectacular
END

在调用时,参数声明失败,并显示错误“将数据类型nvarchar转换为日期时出错”。可以通过如下更改代码来解决:

CREATE OR ALTER PROCEDURE MySchema.MyProcedure
   @myDateTimeParam DATETIME = NULL
AS
BEGIN

    IF @myDateTimeParam IS NULL
        SET @myDateTimeParam = GETDATE();

   -- Do something spectacular
END

但是,假设@myDateTimeParam没有默认值:

CREATE OR ALTER PROCEDURE MySchema.MyProcedure
   @myDateTimeParam DATETIME
AS
BEGIN
   -- Do something spectacular
END

在这种情况下,您不能简单地将GETDATE()传递为如下形式参数:

EXEC MySchema.MyProcedure GETDATE()

因为这也会产生可怕的“将数据类型nvarchar转换为日期时出错”错误。唯一的解决方法是先声明一个变量,然后传递该变量:

DECLARE @myDateTimeParam DATETIME = GETDATE();
EXEC MySchema.MyProcedure @myDateTimeParam;

这是为什么?源数据类型和目标数据类型均为DATETIME。从理论上讲,将GETDATE()的结果用作参数的默认值或形式参数的值时,不应发生数据类型转换错误。

是否出于某种技术原因无法正常工作? MSDN文档中没有任何内容表明它不起作用。

1 个答案:

答案 0 :(得分:4)

文档CREATE PROCEDURE (Transact-SQL) arguments 部分的 default 子标题下对此进行了介绍:

  

参数的默认值。如果为   参数,可以在不指定值的情况下执行该过程   对于该参数。 默认值必须是一个常数,也可以是   。常量值可以采用通配符形式,使其成为   将参数传递到参数中时可以使用LIKE关键字   程序。

强调我的。

GETDATE()不是常量,因此不能使用DEFAULT值。因此,为什么需要使用以下格式,因为GETDATE()的值是在运行时确定的:

CREATE PROC YourProc @Param date = NULL
AS

    IF @Param IS NULL BEGIN
        SET @Param = GETDATE();
    END;
    ...