2010-02-26 5 views
0

У меня есть функция SQL Server, который преобразует NVARCHAR день значение длительности в значение в даты и времени.Преобразуя NVARCHAR Установка длительности дня в DateTime

Формат Продолжительность день > дней <> < часов: минут.> <, например 1.2: 00 в течение одного дня и два часа.

Формат настройки продолжительности дня не может быть изменен, и мы можем быть уверены, что все данные правильно отформатированы и представлены.

Предоставление функции времени начала и установки продолжительности дня должно возвращать время окончания.

Например: 2010-01-02 13:30 ==> 2010-01-03 2:00

Я использую комбинацию CHARINDEX, подстроки и преобразовывать методы для вычисления значения, который является своего рода медленным и упрямым. Есть ли другой способ напрямую преобразовать этот параметр продолжительности дня в значение datetime?

ответ

2

Не из того, что я вижу. Я бы получил такой же бит SQL, как и вы, используя charindex и т. Д. К сожалению, это зависит от формата, в котором хранится дневная продолжительность. Я знаю, что вы не можете его изменить, но если бы он был в другом формате, быть намного проще - то, как я обычно делал это, например, состоит в том, чтобы рационализировать продолжительность до базового блока, например, минут.

Вместо того, чтобы хранить 1,2: 00 в течение 1 дня и 2 часов, это будет (1 * 24 * 60) + (2 * 60) = 1560. Затем это можно использовать в прямом DATEADD на исходную дату (только для даты).

С имеющимся форматом, все подходы, я могу думать о включать использование CHARINDEX и т.д.

+0

Да ... Я знаю, что, но, к сожалению, формат как-то наследие, и я не могу изменить его, как он используется в некоторых других системах. – Drejc

+0

@ Drejc - Я не думаю, что есть другой способ обойти это, чтобы быть честным. Это определенно причина медленной работы? Другая вещь, которую я предлагаю, - не делать вычисления в SQL Server, но возвращать оба поля как есть, и позволить вызывающему коду делать это, что будет лучше работать при манипулировании строкой – AdaTheDev

+0

Это фактически выполняется так, как вы описываете, за исключением одна ситуация, когда расчет должен выполняться на стороне SQL. Это не вызывает никаких медленных ответов или подобных проблем, но это просто уродливое решение. – Drejc

1

Одним из вариантов были бы построить строку с расчетом. Затем вы можете запустить сгенерированный SQL с sp_executesql, указав @enddate в качестве выходного параметра:

declare @startdate datetime 
declare @duration varchar(10) 
declare @enddate datetime 

set @startdate = '2010-01-02 13:30' 
set @duration = '0.12:30' 

declare @sql nvarchar(max) 
set @sql = 'set @enddate = dateadd(mi,24*60*' + 
    replace(replace(@duration,'.','+60*'),':','+') + ', @startdate)' 
exec sp_executesql @sql, 
    N'@startdate datetime, @enddate datetime out', 
    @startdate, @enddate out 

Это создает строку, содержащую set @enddate = dateadd(mi,24*60*0+60*12+30, @startdate), а затем запускает его.

Я сомневаюсь, что это быстрее, чем обычный charindex образом:

declare @pos_dot int 
declare @day int 
declare @hour int 
declare @minute int 

select 
    @pos_dot = charindex('.',@duration), 
    @day = cast(left(@duration, @pos_dot-1) as int), 
    @hour = cast(left(right(@duration, 5), 2) as int), 
    @minute = cast(right(@duration, 2) as int), 
    @enddate = dateadd(mi, 24*60*@day + 60*@hour + @minute, @startdate) 
+0

Huh ... это, конечно, способ сделать это, но он очень нечитабельный, и следующий человек, смотрящий на это, просто скажет FTW;) – Drejc

+1

Вы просили решение без charindex tho;) – Andomar

+0

+1, удивительный! это показывает, почему CHARINDEX важен!вы можете сделать версию Charindex более простой с LEFT() для дней и RIGHT() для минут –

Смежные вопросы