簡體   English   中英

SQL將字符串(日期或文本)轉換為日期

[英]SQL convert string(date or text) to date

我有一個數據庫,其中有一個名為stringNextDue的列,其中包含日期(英國格式)和文本(例如“逾期”,“已完成”)等數據

我正在嘗試創建一個視圖,顯示從現在起一個月內到期的課程:

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

這會引發錯誤:

從字符串轉換日期和/或時間時轉換失敗。

這可能是由於stringNextDue可能包含實際的文本字符串。

我試過用

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

ISDATE只接受美國日期格式,因此忽略了很多實際日期作為字符串

嘗試set dateformat 'dmy' ,修復了IsDate問題,但不能在視圖中使用。

有什么建議?

服務器更新不是一個選項

如果你不能使用新的TRY_CONVERT你可以使用這樣的函數:

注意:這不會像31.06.2016那樣錯誤的日期,如果你需要,你必須修改BETWEEN 1 AND 31 ...

注意2:如果您的文本可能包含xml中禁止的字符,則應替換< with &lt; > with &gt; &&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為你的comparisson外。 這取決於你的需求......

應該可以使用以下替換WHERE子句:

SELECT *
FROM 
  -- sample data
  (values('2015-01-01'),('01-01-2015'), ('x-x-x-x')) mt(NextDateString)
-- Replace WHERE statement with the following
CROSS APPLY
(
  SELECT
    RIGHT('0000'+PARSENAME(REPLACE(mt.NextDateString, '-', '.'), 1),4) yyy,
    RIGHT('0000'+PARSENAME(REPLACE(mt.NextDateString, '-', '.'), 2),4) mmm,
    RIGHT('0000'+PARSENAME(REPLACE(mt.NextDateString, '-', '.'), 3),4) ddd
) x
WHERE 
  x.yyy BETWEEN '1950' AND '2050'
  AND x.mmm BETWEEN '0001' AND '0012'
  AND x.ddd BETWEEN '0001' AND '0031'
  AND  ISDATE(mt.NextDateString) = 1
  AND x.yyy+x.mmm+x.ddd < CONVERT(char(8), DATEADD(MONTH, 1, GETDATE()), 112)

結果:

NextDateString  yyy   mmm   ddd
01-01-2015      2015  0001  0001

謝謝你的建議,

我通過在用戶設置上將語言設置為英語來修復它

EXEC sp_defaultlanguage 'username', 'british'

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM