Mail.ruПочтаМой МирОдноклассникиВКонтактеИгрыЗнакомстваНовостиКалендарьОблакоЗаметкиВсе проекты

Работа с датами в MS SQL

Михаил Гавриленко Ученик (174), на голосовании 1 год назад
Не могу понять как реализовать функцию уже вторую неделю в MS SQL. Она должна получать строку в которой могут содержаться любые символы, в том числе и даты. Функция должна проверить чтобы количество дат было не меньше 4, а также разность всевозможных комбинаций пар этих дат не должна привышать 21 день. Если всё правильно, то функция воозвращает 1, если нет, то 0. Проверял на строке '1.1.2022djdi1.1.2022deqi1.1.2022jdidjei1.1.2022'
Голосование за лучший ответ
oscrn Мастер (1137) 1 год назад
Вот пример кода, надеюсь поймешь
 CREATE FUNCTION CheckDates(@inputString NVARCHAR(MAX)) 
RETURNS BIT
AS
BEGIN
DECLARE @dateRegex NVARCHAR(MAX) = '[0-9]{1,2}[./-][0-9]{1,2}[./-][0-9]{4}'
DECLARE @dateCount INT = (SELECT COUNT(*) FROM STRING_SPLIT(@inputString, ' ') WHERE TRY_CONVERT(DATETIME, value) IS NOT NULL)
DECLARE @datePairs TABLE (date1 DATETIME, date2 DATETIME)
DECLARE @result BIT = 1

-- Проверяем, что количество дат больше или равно 4
IF @dateCount < 4
SET @result = 0
ELSE
BEGIN
-- Извлекаем даты из строки
INSERT INTO @datePairs
SELECT d1.date AS date1, d2.date AS date2
FROM (SELECT value AS date FROM STRING_SPLIT(@inputString, ' ') WHERE TRY_CONVERT(DATETIME, value) IS NOT NULL) d1
CROSS JOIN (SELECT value AS date FROM STRING_SPLIT(@inputString, ' ') WHERE TRY_CONVERT(DATETIME, value) IS NOT NULL) d2
WHERE d1.date < d2.date

-- Проверяем, что разность между всевозможными парами дат не превышает 21 день
IF EXISTS (SELECT 1 FROM @datePairs WHERE DATEDIFF(DAY, date1, date2) > 21)
SET @result = 0
END

RETURN @result
END
Михаил ГавриленкоУченик (174) 1 год назад
Возвращает 0
Angrom Мудрец (10032) 1 год назад
Попробуй так:
 CREATE FUNCTION CheckDates(@inputString VARCHAR(MAX)) 
RETURNS INT
AS
BEGIN
DECLARE @dateList TABLE (dateValue DATE)

DECLARE @pos INT
DECLARE @len INT
DECLARE @dateString VARCHAR(MAX)
DECLARE @dateValue DATE

SET @pos = 1
WHILE @pos <= LEN(@inputString)
BEGIN
SET @len = CHARINDEX('.', @inputString, @pos) - @pos
IF @len < 0
SET @len = LEN(@inputString) - @pos + 1

SET @dateString = SUBSTRING(@inputString, @pos, @len)

BEGIN TRY
SET @dateValue = CAST(@dateString AS DATE)
INSERT INTO @dateList (dateValue) VALUES (@dateValue)
END TRY
BEGIN CATCH
-- do nothing
END CATCH

SET @pos = @pos + @len + 1
END

DECLARE @dateCount INT
SET @dateCount = (SELECT COUNT(*) FROM @dateList)

IF @dateCount < 4
RETURN 0

DECLARE @validPairs TABLE (date1 DATE, date2 DATE)
INSERT INTO @validPairs (date1, date2)
SELECT d1.dateValue, d2.dateValue
FROM @dateList d1, @dateList d2
WHERE d1.dateValue < d2.dateValue
AND DATEDIFF(DAY, d1.dateValue, d2.dateValue) <= 21

IF (SELECT COUNT(*) FROM @validPairs) = (SELECT COUNT(*) FROM @dateList) * (SELECT COUNT(*) FROM @dateList) / 2
RETURN 1
ELSE
RETURN 0
END
Вызывать следующим образом:
 SELECT dbo.CheckDates('1.1.2022djdi1.1.2022deqi1.1.2022jdidjei1.1.2022')  
Этот запрос должен вернуть 1, потому что все условия были выполнены.
(не тестировал)
Похожие вопросы