首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >SQL Server如何确定隐式日期时间转换的格式?

SQL Server如何确定隐式日期时间转换的格式?
EN

Stack Overflow用户
提问于 2012-05-01 22:11:56
回答 3查看 27.2K关注 0票数 21
代码语言:javascript
复制
declare @str_datetime varchar(50)
set @str_datetime='30-04-2012 19:01:45' -- 30th April 2012
declare @dt_datetime datetime
select @dt_datetime=@str_datetime

这给出了以下错误:

消息242,第16级,状态3,第4行

varchar数据类型到datetime数据类型的转换导致值超出范围。

我的问题是,SQL Server如何决定使用哪种格式进行隐式日期时间转换?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2012-05-01 23:03:05

这可能取决于多种因素-操作系统的区域设置、当前用户的语言和日期格式设置。默认情况下,Windows使用US English,用户的设置为US EnglishMDY

但这里有一些例子来说明这种情况是如何改变的。

用户正在使用英国语言设置:

代码语言:javascript
复制
-- works:
SET LANGUAGE BRITISH;
SELECT CONVERT(DATETIME, '30-04-2012 19:01:45');

-- fails:
SELECT CONVERT(DATETIME, '04/13/2012');
GO

(错误)

消息242,第16级,状态3,第5行

varchar数据类型到datetime数据类型的转换导致值超出范围。

用户正在使用Français:

代码语言:javascript
复制
-- works:
SET LANGUAGE FRENCH;
SELECT CONVERT(DATETIME, '30-04-2012 19:01:45');

-- fails:
SELECT CONVERT(DATETIME, '04/13/2012');
GO

(错误)

消息242,第16级,状态3,第1行

La conversion d‘’un type de données varchar en type de données datetime a créune valeur hors limites。

用户再次使用Français:

代码语言:javascript
复制
SET LANGUAGE FRENCH;

-- fails (proving that, contrary to popular belief, YYYY-MM-DD is not always safe):
SELECT CONVERT(DATETIME, '2012-04-30');
GO

(错误)

消息242,第16级,状态3,第1行

La conversion d‘’un type de données varchar en type de données datetime a créune valeur hors limites。

用户正在使用DMY而不是MDY:

代码语言:javascript
复制
SET LANGUAGE ENGLISH;
SET DATEFORMAT DMY;

-- works:
SELECT CONVERT(DATETIME, '30-04-2012 19:01:45');

-- fails:
SELECT CONVERT(DATETIME, '04-30-2012');
GO

(错误)

消息242,第16级,状态3,第2行

varchar数据类型到datetime数据类型的转换导致值超出范围。

你最好总是使用ISO标准的、非区域的、安全的、明确的日期格式。我通常推荐的两个是:

代码语言:javascript
复制
YYYYMMDD                  - for date only.
YYYY-MM-DDTHH:MM:SS[.mmm] - for date + time, and yes that T is important.

所有这些都不会失败:

代码语言:javascript
复制
SET DATEFORMAT MDY;
SET LANGUAGE ENGLISH;
SELECT CONVERT(DATETIME, '20120430');
SELECT CONVERT(DATETIME, '2012-04-30T19:01:45');
SET LANGUAGE FRENCH;
SELECT CONVERT(DATETIME, '20120430');
SELECT CONVERT(DATETIME, '2012-04-30T19:01:45');
SET LANGUAGE BRITISH;
SELECT CONVERT(DATETIME, '20120430');
SELECT CONVERT(DATETIME, '2012-04-30T19:01:45');
SET DATEFORMAT DMY;
SELECT CONVERT(DATETIME, '20120430');
SELECT CONVERT(DATETIME, '2012-04-30T19:01:45');

因此,我强烈建议,不要让用户键入自由文本日期格式(或者您自己使用不可靠的格式),控制您的输入字符串,并确保它们遵循这些安全格式之一。然后,用户的设置或底层区域设置将不再重要,您的日期将始终被解释为预期的日期。如果您当前允许用户在表单的文本字段中输入日期,请停止此操作,并实现一个日历控件或至少一个选择列表,这样您就可以最终控制传递回SQL Server的字符串格式。

要了解一些背景,请阅读Tibor Karaszi的"The ultimate guide to the datetime datatypes"和我的帖子"Bad Habits to Kick : Mis-handling date / range queries."

票数 30
EN

Stack Overflow用户

发布于 2012-05-01 22:20:34

默认情况下,除非已安装SQL server的本地化版本,否则SQL Server的日期格式为美国日期格式MM/DD/YY、。此设置适用于需要此功能的应用程序的部署方式,以确保在使用该应用程序的所有平台和位置上以相同的格式使用和插入日期。

但是,在某些情况下,日期必须采用DD/MM/YY格式,因为许多国家/地区使用此格式,而不是美国默认的MM/DD/YY格式。对于分布在世界各地的国际应用程序来说,这尤其是一个问题。

Source

因此,您需要做的是提前设置日期格式,如下所示:

代码语言:javascript
复制
SET DATEFORMAT dmy
GO

然后你的查询就可以工作了。

票数 1
EN

Stack Overflow用户

发布于 2014-01-16 00:43:43

您还可以为每个登录帐户和/或每个将来添加的登录帐户更改默认日期格式(无需在每个会话中执行"SET DATEFORMAT“。

您可以进入SQL Management Studio / Security / Logins。右键循环登录,然后单击属性。您将在底部看到“默认语言”。

如果你想确保将来添加的任何登录都使用“好”的语言。右键单击服务器根目录,然后单击属性和高级页面。还有一个选项“默认语言”,用于新创建的登录。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/10398921

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档