【问题标题】:Transforming nvarchar day duration setting into datetime将 nvarchar 日持续时间设置转换为日期时间
【发布时间】:2010-02-26 23:56:37
【问题描述】:

我有一个 SQL Server 函数,它可以将 nvarchar 持续时间设置转换为 datetime 值。

一天的持续时间格式是>days<.>hours<:>minutes,例如1.2:00代表一天两小时。

白天持续时间设置的格式无法更改,我们可以确保所有数据都正确格式化并呈现。

给函数一个开始时间和持续时间设置它应该返回结束时间。

例如:2010-01-02 13:30 ==> 2010-01-03 2:00

我使用 charindex、substring 和 convert 方法的组合来计算值, 这有点缓慢和尴尬。有没有其他方法可以直接将这一天的持续时间设置转换为日期时间值?

【问题讨论】:

    标签: sql sql-server


    【解决方案1】:

    不是我能看到的。我最终会得到与您类似的 SQL,使用 charindex 等。不幸的是,这取决于存储日期的格式。我知道您无法更改它,但如果它采用不同的格式,那么它更容易 - 例如,我通常这样做的方式是将持续时间合理化为分钟等基本单位。

    不是将 1.2:00 存储 1 天 2 小时,而是 (1 * 24 * 60) + (2 * 60) = 1560。然后可以在原始日期(日期仅部分)。

    使用您拥有的格式,我能想到的所有方法都涉及使用 CHARINDEX 等。

    【讨论】:

    • 是的......我知道,但不幸的是,格式有点旧,我无法更改它,因为它在其他一些系统中使用。
    • @Drejc - 老实说,我认为没有其他方法可以解决。这绝对是性能缓慢的原因吗?我建议的另一件事是不要在 SQL Server 中进行计算,而是按原样返回两个字段并让调用代码执行它,这将在字符串操作方面表现更好
    • 这实际上是按照您描述的方式完成的,除了一种情况,必须在 SQL 端执行计算。它不会导致任何缓慢的响应或类似的问题,但它只是一个丑陋的解决方案。
    • @Drejc - 至少这是一回事。您已将其包装在一个函数中,该函数至少将其保存在一个位置,并且很好地分开。
    【解决方案2】:

    另一种方法是使用计算构建一个字符串。然后您可以使用sp_executesql 运行生成的SQL,指定@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)
    

    【讨论】:

    • 嗯......这当然是一种方法,但它非常不可读,下一个看到这个的人只会说 FTW ;)
    • 您要求一个没有 charindex 的解决方案;)
    • +1,太棒了!这表明为什么 CHARINDEX 很重要!!你可以让你的 charindex 版本更简单,用 LEFT() 表示天数,用 RIGHT() 表示分钟数
    猜你喜欢
    • 1970-01-01
    • 2015-09-23
    • 2021-01-17
    • 2014-11-19
    • 1970-01-01
    • 2012-11-26
    • 1970-01-01
    • 1970-01-01
    • 2021-11-12
    相关资源
    最近更新 更多