【问题标题】:Convert '01-Sep-2017' to '01/09/2017' in T-SQL?在 T-SQL 中将 '01-Sep-2017' 转换为 '01/09/2017'?
【发布时间】:2018-09-04 17:42:51
【问题描述】:

我在 C#/WPF 中开发了一个应用程序,它以两种格式在表中保存 nvarchar 列,一种是连字符,另一种是前破折号,如下所示:'01-Sep-2017' 到 '01/09 /2017'

最简单的解决方案是在查询时将格式为“01-Sep-2017”的日期转换为“01/09/2017”并获取应有的数据?

我该怎么做?

或者我应该使用某种更新语句将日期转换并保存为适当的格式?

注意:但如果这样做并不容易。我有两种格式的不同数据。它应该折叠到同一日期。

【问题讨论】:

  • 你真的应该把日期保存为日期时间。
  • ALTER TABLE xxxx ALTER COLUMN yyyy DATETIME(先删除所有现有的)
  • @Vlad 是时候去找另一家公司了
  • 回到他们身边,告诉他们他们错了。您可以随时将它们推荐给我或地球上任何其他 SQL 专家,包括许多 Microsoft 文章。
  • ...或者只是让他们阅读 Aaron Bertrand 的 Bad habits to kick : choosing the wrong data type

标签: c# sql sql-server sql-server-2008 tsql


【解决方案1】:

正如 cmets 上的几乎每个人以及任何知道自己在数据库方面做什么的人所指出的那样,将日期存储为字符串是一个糟糕的主意,只会导致问题。
这是一个(非常)简短的原因列表:

  • 无法验证存储的值实际上是日期 - 没有什么能阻止您将 '13/09/2017' 存储在一行中,将 'Banana' 存储在另一行中。
  • 无法验证日期的有效性 - 没有什么能阻止您存储 '13/14/1000''31-Feb-2020' 甚至 '01-Dev-1999'
  • 如果不先转换为日期,就无法使用任何数据库内置的日期/日期时间函数。
  • 如果不先转换为日期,就无法执行日期范围搜索。
  • 无法强制执行任何类型的基于日期的逻辑(即您有一个开始日期和结束日期列,并且您希望确保结束日期为空或晚于开始日期)
  • 日期的字符串表示是特定于文化的。 '01-Dez-2017' 是 2017 年 12 月 1 日,例如德语。
  • .Net 框架 DateTime 结构直接映射到 SQL Server DateDateTimeDateTime2 数据类型。将日期存储为字符串意味着您必须在应用层和数据库之间传递日期。

说了这么多,如果您仍然绝对不能重构您的数据库以正确存储日期,您可以使用convert 将日期的字符串表示更改为正确的日期。由于它是 2008 版本,Try_convert 不在讨论范围内,因此您需要使用几个常用的表表达式来处理日期的不同字符串表示:

CREATE TABLE Terrible
(
    StringDate varchar(20)
);

INSERT INTO Terrible VALUES
('01-Sep-2017'), ('01/09/2017'),('Banana'),('30/02/2017');


SET DATEFORMAT DMY;
SELECT CONVERT(char(10), DateValue, 103)
FROM
(
    SELECT CONVERT(Date, REPLACE(StringDate, '-', ' '), 106) As DateValue
    FROM Terrible
    WHERE StringDate LIKE '[0-9][0-9]-[a-z|A-Z][a-z|A-Z][a-z|A-Z]-[0-9][0-9][0-9][0-9]%'

    UNION ALL

    SELECT CONVERT(Date, StringDate, 103) As DateValue
    FROM Terrible
    WHERE StringDate LIKE '[0-9][0-9]/[0-9][0-9]/[0-9][0-9][0-9][0-9]'
    AND ISDATE(StringDate) = 1
) ProperDates

【讨论】:

    【解决方案2】:
    SELECT CONVERT (VARCHAR (20), YourField, 103) FROM YourTable
    

    您可以在此处查看格式:https://docs.microsoft.com/en-us/sql/t-sql/functions/cast-and-convert-transact-sql

    【讨论】:

    • 所有的cmets都已经制作好了。至少可以说,这可能不是最佳做法。
    【解决方案3】:

    您需要确保您的 SQL Server 以英文安装。一旦你确定转换函数应该完成这项工作

    SELECT CONVERT(DATETIME, '02-Sep-2017')
    

    如果您需要将其转换为您共享的字符串:

    SELECT CONVERT(VARCHAR, CONVERT(DATETIME, '02-Sep-2017'), 103)
    

    样式参考here

    【讨论】:

    • hmm,试过了,我得到了这个错误:将 nvarchar(50) 数据类型转换为日期时间数据类型导致值超出范围。
    • 嗯。我在子查询中使用子查询。需要搜索信息。
    • @Vlad 我相信一个值破坏了转换,你的系统是英文的吗?
    • 是的,我正在转换的字段可以有 NULL 值。
    • @harkoded 嗯,这很奇怪。但是为什么我会收到错误消息。如果我跳过空值,它会起作用
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-02-17
    • 2018-02-05
    • 1970-01-01
    • 1970-01-01
    • 2017-05-28
    相关资源
    最近更新 更多