考虑以下存储过程:
CREATE OR ALTER PROCEDURE MySchema.MyProcedure
@myDateTimeParam DATETIME = GETDATE()
AS
BEGIN
-- Do something spectacular
END
Run Code Online (Sandbox Code Playgroud)
调用时,参数声明失败并显示错误“将数据类型 nvarchar 转换为日期时出错”。这可以通过如下更改代码来解决:
CREATE OR ALTER PROCEDURE MySchema.MyProcedure
@myDateTimeParam DATETIME = NULL
AS
BEGIN
IF @myDateTimeParam IS NULL
SET @myDateTimeParam = GETDATE();
-- Do something spectacular
END
Run Code Online (Sandbox Code Playgroud)
但是,假设@myDateTimeParam没有默认值:
CREATE OR ALTER PROCEDURE MySchema.MyProcedure
@myDateTimeParam DATETIME
AS
BEGIN
-- Do something spectacular
END
Run Code Online (Sandbox Code Playgroud)
在这种情况下,您不能简单地GETDATE()作为形式参数传递,如下所示:
EXEC MySchema.MyProcedure GETDATE()
Run Code Online (Sandbox Code Playgroud)
因为这也会产生可怕的“将数据类型 nvarchar 转换为日期时出错”的错误。唯一的解决方法是首先声明一个变量,然后传递该变量:
DECLARE @myDateTimeParam DATETIME = GETDATE();
EXEC MySchema.MyProcedure @myDateTimeParam;
Run Code Online (Sandbox Code Playgroud)
为什么是这样?源数据类型和目标数据类型都是DATETIME. 理论上,GETDATE()无论是作为参数的默认值还是形参的值,都不会发生数据类型转换错误。
是否有一些技术原因这不起作用?MSDN 文档中没有任何内容表明它不应该工作。
这在文档CREATE PROCEDURE (Transact-SQL)中包含在参数部分的默认副标题下:
参数的默认值。如果为参数定义了默认值,则无需为该参数指定值即可执行该过程。默认值必须是常量,也可以是 NULL。常量值可以采用通配符的形式,从而可以在将参数传递到过程中时使用 LIKE 关键字。
强调我的。
GETDATE()不是常数,因此不能用作 aDEFAULT值。因此,为什么您需要使用以下格式,因为 的值GETDATE()是在运行时确定的:
CREATE PROC YourProc @Param date = NULL
AS
IF @Param IS NULL BEGIN
SET @Param = GETDATE();
END;
...
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2300 次 |
| 最近记录: |