如何使从 varchar 到 datetime 的转换具有确定性?
按照这个问题的传统并根据文档,如何一个使这个函数具有确定性:
ALTER FUNCTION [udf_DateTimeFromDataDtID]
(
@DATA_DT_ID int -- In form YYYYMMDD
)
RETURNS datetime
WITH SCHEMABINDING
AS
BEGIN
RETURN CONVERT(datetime, CONVERT(varchar, @DATA_DT_ID))
END
或者这个(因为字符串/日期文字 - 是的,我也尝试过“1900-01-01”):
ALTER FUNCTION udf_CappedDate
(
@DateTimeIn datetime
)
RETURNS datetime
WITH SCHEMABINDING
AS
BEGIN
IF @DateTimeIn < '1/1/1900'
RETURN '1/1/1900'
ELSE IF @DateTimeIn > '1/1/2100'
RETURN '1/1/2100'
RETURN @DateTimeIn
END
In the tradition of this question and in light of the documentation, how does one make this function deterministic:
ALTER FUNCTION [udf_DateTimeFromDataDtID]
(
@DATA_DT_ID int -- In form YYYYMMDD
)
RETURNS datetime
WITH SCHEMABINDING
AS
BEGIN
RETURN CONVERT(datetime, CONVERT(varchar, @DATA_DT_ID))
END
Or this one (because of the string/date literals - and yes, I've also tried '1900-01-01'):
ALTER FUNCTION udf_CappedDate
(
@DateTimeIn datetime
)
RETURNS datetime
WITH SCHEMABINDING
AS
BEGIN
IF @DateTimeIn < '1/1/1900'
RETURN '1/1/1900'
ELSE IF @DateTimeIn > '1/1/2100'
RETURN '1/1/2100'
RETURN @DateTimeIn
END
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
从您链接的文章中:
您需要在到日期时间的转换中使用样式参数。
例如:
除非不要使用 121...
From the articles you linked:
You need to use a style parameter in your conversions to datetime.
For example:
Except don't use 121...
BOL 表示如果指定了 style 参数,则
CONVERT
具有日期时间确定性。 因此,如果您将第一个 UDF 更改为:如果我正确理解文档,那么它应该是确定性的。
想必,同样的技巧也可以用在您的第二个 UDF 中:
我真的希望有一种方法可以在 T-SQL 中指定日期时间文字。
编辑:
正如Arvo在评论中指出的(谢谢,Arvo),可以使用ODBC时间戳文字格式(即使使用OLE DB时),所以第二个函数上面可以更好地写为:
并且到日期时间的转换是在编译时而不是执行时完成的。 请注意,日期的格式必须非常具体(请参阅 Arvo 的日期时间链接数据类型):
BOL says that
CONVERT
is deterministic with datetimes if the style parameter is specified. So if you change the first UDF to:Then it should be deterministic, if I understand the docs correctly.
Presumably, the same trick could be used in your second UDF:
I really wish there were a way to specify datetime literals in T-SQL.
EDIT:
As pointed out by Arvo in the comments (thank you, Arvo), the ODBC timestamp literal format can be used (even when using OLE DB) so the second function above could be better written as:
and the conversion to datetime is done at compile time instead of execution time. Note that the format of the date has to be very specific (see Arvo's link to the datetime data type):