通过文件名SQL创建日期

时间:2019-07-09 21:38:35

标签: sql-server datetime

我有一个带有附件表的数据库。我需要按日期对附件进行排序,然后将旧数据和日期放入新表中。 我无权访问文件本身,我想根据文件名在此表中创建日期。

所需的输出为YYYY MM DD。不必担心HH,只需将其设置为0。

SELECT CONVERT(
            DATETIME, CONVERT(VARCHAR(40), '2015-03-20')
            , 120)

期望的输出,例如:2015-03-20 00:00:00.000

我本来尝试对文件名使用LEFT(RIGHT。但是由于有时会有多余的字符或日期格式颠倒,因此无法正常工作。 我已经尝试了https://www.sqlservercentral.com/forums/topic/get-date-part-from-a-filename-string的一些解决方案,但是再次使用不同的文件名格式使得这些解决方案中的任何一个都不起作用。

----try1:   
GO
DECLARE @S VARCHAR(MAX)

SET @S = '42223_bob_2015-03-20-022535.pdf'
--SET @S = '43661_bill_2015-04-29-113348 (1).pdf'
--SET @S = 'Invoice Revenue By Group-22-05-2017 12:09:27pm.xls'
--SET @S = 'Invoice Revenue By Group-2018-05-11-11-05-37.xls'

SELECT @S AS Filename
       , LEFT(RIGHT(@S,21),10) AS r21_l10
GO

----try2:
DECLARE
@Split CHAR(1)
,@X XML
, @S VARCHAR(MAX)

SET @S = '42223_bob_2015-03-20-022535.pdf'
--SET @S = '43661_bill_2015-04-29-113348 (1).pdf'
--SET @S = 'Invoice Revenue By Group-22-05-2017 12:09:27pm.xls'
--SET @S = 'Invoice Revenue By Group-2018-05-11-11-05-37.xls'

SET @Split = '-'

SELECT
@X = CONVERT(XML,'<root><s>' + REPLACE(@S,@Split,'</s><s>')+'</s></root>')
SET ROWCOUNT 1
SELECT
DateValue
FROM
(SELECT (CASE 
                 WHEN LEN(Value) = 8 AND ISDATE(Value) = 1 
                 THEN CAST(Value AS DATE)
         ELSE NULL
         END) AS DateValue
FROM (
          SELECT T.c.value('.','VARCHAR(MAX)') AS [Value] 
          FROM @X.nodes('/root/s') T (c)
    ) Result1
WHERE ISDATE(Value) = 1
) Result2
WHERE DateValue IS NOT NULL
ORDER BY DateValue DESC
SET ROWCOUNT 0

-该解决方案由John Cappelletti提供

GO

/****** Object:  UserDefinedFunction [dbo].[fn_FileNameDateExtract]    
Script 
Date: 11/07/2019 15:16:23 PM ******/
SET ANSI_NULLS ON
GO

SET QUOTED_IDENTIFIER ON
GO

-- =============================================
-- Author:      John Cappelletti
-- =============================================
CREATE FUNCTION [dbo].[fn_FileNameDateExtract]
(
@filename   NVARCHAR(MAX)
)
RETURNS
DATE
AS
BEGIN
SET @filename =
TRY_CONVERT(date,SUBSTRING(@filename
   ,COALESCE(
             NULLIF(PATINDEX('%[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]%',@filename),0)
            ,NULLIF(PATINDEX('%[0-9][0-9]-[0-9][0-9]-[0-9][0-9][0-9][0-9]%',@filename),0)
    ),10));
RETURN @filename
END

GO

1 个答案:

答案 0 :(得分:2)

也许patindex()在这里会有所帮助。我们找到字符串####-##-##的位置,然后找到try_convert()的日期

如果模式不匹配,则将返回NULL值

示例

Declare @S varchar(200) = '42223_bob_2015-03-20-022535.pdf'

Select try_convert(date,substring(@S,nullif(patindex('%[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]%',@S),0),10))

返回

2015-03-20
  

编辑-更新为备用模式

--Declare @S varchar(200) = '42223_bob_2015-03-20-022535.pdf'
Declare @S varchar(200) = 'Invoice Revenue By Group-22-05-2017 12:09:27pm.xls'

Set DateFormat DMY

Select try_convert(date,substring(@S
       ,coalesce(
                 nullif(patindex('%[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]%',@S),0)
                ,nullif(patindex('%[0-9][0-9]-[0-9][0-9]-[0-9][0-9][0-9][0-9]%',@S),0)
        ),10))