0

我有一个返回datetime2.

...
MS_VatToDate (@vYEAR smallint, @vMONTH smallint, @vDAY smallint)  

...

DECLARE @VatDate DATETIME2;
DECLARE @VatDateText VARCHAR(11);

SET @VatDateText = CAST(@vYEAR AS VARCHAR(4)) + '-' + 
                   CAST(@vMONTH AS VARCHAR(2)) + '-' +
                   CAST(@vDAY AS VARCHAR(2));

SET @VatDate = CONVERT(DATETIME2, @VatDateText, 126);
RETURN(@VatDate);

当我指定数据时,它工作得很好,但是当我指定某个范围时,我得到一个错误。

从字符串转换日期和/或时间时转换失败。

当我尝试将这个函数应用于整个数据库时发生了同样的事情,但一开始我得到了正确的结果,然后最后出现了同样的错误。

4

3 回答 3

1

为什么要编写自己的函数?

SQL Server 提供datefromparts(),因此您只需编写:

select datefromparts(2018, 11, 30)

如果你想要一个datetime2

select convert(datetime2, datefromparts(2018, 11, 30))

或者datetime2fromparts()

select datetime2fromparts(2018, 11, 30, 0, 0, 0)

对 SQL Server 2008 R2 的支持将于 2019 年 7 月结束,因此您应该在支持结束之前进行更新。

在旧系统中,您可以在没有格式的情况下进行转换——除非您的默认日期格式是 YDM:

 set @VatDateText = cast(@vYEAR as varchar(4))+'-'+cast(@vMONTH as varchar(2))+'-'+cast(@vDAY as varchar(2));
 set @VatDate     = convert(datetime2, convert(date, @VatDateText));
于 2018-11-30T12:56:01.653 回答
0

如果您不能使用DATEFROMPARTS(自 SQL Server 2012 起可用),请删除破折号并直接转换字符串。无论您的语言环境和日期设置如何,“20181130”都将成功转换为日期。在这种情况下,也可能是您的数据中有一位数的月/日,并且构造的字符串无效,因此请添加前导零。

declare @VatDate datetime2;
declare @VatDateText varchar(11);

 set @VatDateText = cast(@vYEAR as varchar(4))+right('0' +cast(@vMONTH as varchar(2)), 2)+right('0' + cast(@vDAY as varchar(2)), 2);
 set @VatDate     = cast(@VatDateText as datetime2);
 return(@VatDate);
于 2018-11-30T13:08:02.170 回答
0

我想你可以ISDATE在转换之前使用函数:

DECLARE @VatDate datetime2;
DECLARE @VatDateText varchar(11);
SET @VatDateText = CAST(@vYEAR as varchar(4)) + '-' + CAST(@vMONTH as varchar(2)) + '-' + CAST(@vDAY as varchar(2));

IF ISDATE(@VatDateText) = 1
    SET @VatDate = convert(datetime2, @VatDateText, 126);
ELSE
    PRINT @VatDateText + ' is invalid';

SELECT /* RETURN */ @VatDate;
于 2018-11-30T13:49:04.210 回答