SQL 将字符串(日期或文本)转换为日期 [英] SQL convert string(date or text) to date

查看:70
本文介绍了SQL 将字符串(日期或文本)转换为日期的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个数据库,其中有一个名为 stringNextDue 的列,其中包含日期(英国格式)和文本(例如过期"、已完成")等数据

I have a database which has a column called stringNextDue that contains data like dates (UK format) and text (e.g "overdue", "completed")

我正在尝试创建一个视图,显示从现在起一个月内到期的课程:

I am trying to create a view that shows courses that are due within a month from now:

WHERE 
    CONVERT(DATETIME, mt.stringNextDue , 103) < DATEADD(MONTH, 1, GETDATE())

这会引发错误:

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

Conversion failed when converting date and/or time from character string.

这可能是因为 stringNextDue 可能包含实际的文本字符串.

Which is probably due to the fact that stringNextDue may contain actual strings of text.

我尝试使用

WHERE 
    ISDATE(mt.NextDateString) = 1 
    AND CONVERT(DATETIME, mt.stringNextDue , 103) < DATEADD(MONTH, 1, GETDATE())

但是 ISDATE 只接受美国日期格式,因此忽略了许多实际日期作为字符串

But ISDATE only accepts US date formats therefore ignoring a lot of actual dates as strings

尝试了 set dateformat 'dmy',它解决了 IsDate 问题,但无法在视图中使用.

Tried set dateformat 'dmy', which fixed the IsDate issue, but it cannot be used in views.

有什么建议吗?

服务器更新不是一种选择

Server update is not an option

推荐答案

如果你不能使用新的 TRY_CONVERT 你可以使用这样的函数:

If you cannot use the new TRY_CONVERT you might use a function like this:

注意:这不会像 31.06.2016 这样的错误日期,如果你需要这个,你必须修改 BETWEEN 1 AND 31...

Attention: This will not catch a wrong date like 31.06.2016, you'd have to modify the BETWEEN 1 AND 31 if you need this...

注意2:如果您的文本可能包含xml中禁止的字符,您应该将<替换为&lt;>替换为&gt;&&amp; ...

Attention2: If your text might include characters forbidden in xml you should replace < with &lt;, > with &gt; and & with &amp; ...

CREATE FUNCTION dbo.TestDate(@TestString VARCHAR(100))
RETURNS DATE
AS
BEGIN
    DECLARE @x XML=CAST('<x>' + REPLACE(@TestString,'.','</x><x>') + '</x>' AS XML)

    DECLARE @p1 VARCHAR(10) = @x.value('x[1]','varchar(10)');
    DECLARE @p2 VARCHAR(10) = @x.value('x[2]','varchar(10)');
    DECLARE @p3 VARCHAR(10) = @x.value('x[3]','varchar(10)');

    IF    LEN(@p1)=2 AND ISNUMERIC(@p1)=1 AND CAST(@p1 AS INT) BETWEEN 1 AND 31
      AND LEN(@p2)=2 AND ISNUMERIC(@p2)=1 AND CAST(@p2 AS INT) BETWEEN 1 AND 12
      AND LEN(@p3)=4 AND ISNUMERIC(@p3)=1 AND CAST(@p3 AS INT) BETWEEN 1900 AND 2100

    RETURN CONVERT(DATETIME, @TestString , 103);

    RETURN NULL;
END
GO

SELECT
  dbo.TestDate('overdue') AS SureNoDate
 ,dbo.TestDate('01.04.2016') AS EuropeanDate
 ,dbo.TestDate('2016.04.01') AS WrongFormat
 ,dbo.TestDate('01.13.2016') AS BadDate;
GO

DROP FUNCTION dbo.TestDate;

结果

SureNoDate  EuropeanDate    WrongFormat BadDate
NULL        2016-04-01      NULL        NULL

您可能会回传一个有效日期 (RETURN GETDATE() ?) 而不是 RETURN NULL 用于外部比较.这取决于您的需求...

You might pass back a valid date (RETURN GETDATE() ?) instead of RETURN NULL for your comparisson outside. This depends on your needs...

这篇关于SQL 将字符串(日期或文本)转换为日期的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆