Дата создания из имени файла SQL - PullRequest
1 голос
/ 10 июля 2019

У меня есть база данных с таблицей вложений.Мне нужно отсортировать вложения по дате, поместив старые данные плюс дату в новую таблицу.У меня нет доступа к самим файлам, я хочу создать даты в этой таблице на основе имени файла.

Желаемый вывод - ГГГГ ММ ДД.Не беспокойтесь о ЧЧ, просто собираюсь установить их как 0.

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

желаемый вывод, например: 2015-03-20 00: 00: 00.000

Я попытался ВЛЕВО (ВПРАВО наимя файла изначально. Однако, поскольку иногда встречаются дополнительные символы или формат даты меняется, это не работает. Я пробовал некоторые решения из 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

- решение предоставлено Джоном Каппеллетти

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 Ответ

2 голосов
/ 10 июля 2019

Возможно, 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))
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...