Sql 使用函数时从字符串转换日期和/或时间时,转换失败

Sql 使用函数时从字符串转换日期和/或时间时,转换失败,sql,sql-server,tsql,datetime,Sql,Sql Server,Tsql,Datetime,我有一个函数,它返回一个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 A

我有一个函数,它返回一个
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);
当我指定数据时,它工作得很好,但当我指定某个范围时,我会得到一个错误

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


当我尝试将此函数应用于整个数据库时,也发生了同样的情况,但一开始我得到了正确的结果,最后还是相同的错误。

为什么要编写自己的函数

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

select datefromparts(2018, 11, 30)
如果您想要一个
datetime2

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

对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));
如果无法使用(自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);
我想您可以在转换之前使用函数:

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;

您必须注意,
datefromparts()
将仅适用于SQL Server 2012及更高版本。可能使用较旧版本的SQL Server?2008仍在此处:(“datefromparts”不是可识别的内置函数名。是否删除了破折号?此代码有效。另一种可能的解释是,您试图转换无效数据,例如非闰年的2月29日,或类似的数据。您的代码看起来很正常,但如果数字无效,则代码将失败,例如,您为4月或2日指定了319用于2018年2月。恐怕大多数其他函数(datefrompart等)都会给出相同的错误。它的工作形式是
SET@VatDateText=CAST(@vRok as varchar(4))+'-'+CAST(@vMiesiac as varchar(2))+'-'+CAST(@vDzien as varchar(2));IF ISDATE(@VatDateText)=1 SET@VatDate=convert(datetime2,@VatDateText,126);ELSE设置@VatDate=''return(@VatDate);
但我想对于生产来说,它不是完美的形式。如果您有无效的日期,则必须修复它们。在4月31日搜索记录没有意义。
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;