在 SQL Server 中插入经过的时间

Posted

技术标签:

【中文标题】在 SQL Server 中插入经过的时间【英文标题】:Insert Elapsed Time in SQL Server 【发布时间】:2014-08-15 16:57:46 【问题描述】:

我想使用 C# 秒表将经过的时间插入 SQL Server,以便我们可以使用 SQL 脚本平均时间。

var stopwatch = new Stopwatch();
stopwatch.Start();
stopwatch.Stop();
var elapsedTime = stopwatch.Elapsed;

我是这样插入时间的……

cmd.Parameters.Add("@ElapsedTime", SqlDbType.Time);

数据库中的数据类型是...

ElapsedTime(time(7),null)

收到此错误...

SqlDateTime overflow. Must be between 1/1/1753 12:00:00 AM and 12/31/9999 11:59:59 PM.

我只想像这样在数据库中插入经过的时间...

00:01:44.9383728

这是我将如何放入数据库...

internal bool TimesToSql(TimeSpan elapsedTime)
    
        try
        
            const string statement = "INSERT INTO Database.dbo.TestProgress(MachineName, ElapsedTime) " +
                                     "VALUES(@MachineName, @ElapsedTime)";
            var conn = new SqlConnection(ConnectionStringLocalDb());
            var cmd = new SqlCommand(statement, conn);
            var machineName = Environment.MachineName;
            cmd.Parameters.Add("@MachineName", SqlDbType.NVarChar);
            cmd.Parameters.Add("@ElapsedTime", SqlDbType.Time);
            //
            cmd.Parameters["@MachineName"].Value = Environment.MachineName;
            cmd.Parameters["@ElapsedTime"].Value = elapsedTime;
            conn.Open();
            cmd.ExecuteNonQuery();
            conn.Close();

            return true;

        
        catch (Exception exception)
        
            _logger.Log(Loglevel.Error, "Boom: 0", exception.Message);
            return false;
        
    

最终目标是从假设 x 的经过时间中获取平均时间,如果我可以使用字符串做到这一点,那么我会将它们格式化为字符串

【问题讨论】:

为什么将类型设为time(7)?那是一天中的某个时间,而不是经过的时间。 (尽管您的错误消息有点令人困惑。)您在哪里为参数指定 value?如果我们能看到更多代码会有所帮助... @Jon 它应该只是一个 int 不是吗? 好吧,看起来 SQL Server 并没有真正拥有一种映射到 TimeSpan 的类型。您可能想要存储多个刻度。但它抱怨 SqlDateTime 溢出的事实向我表明,它甚至可能不是这个参数。你能想出一个简短但完整的程序来演示这个问题吗?你的 SQL 是什么样的? @JonSkeet 我添加了将时间插入表中的 SQL 代码 What is the best way to represent a timespan in SQL Server CE? 的可能重复项(与非 ce 完全相关)。 【参考方案1】:

您究竟想对数据库中的时间跨度做什么?如果您只想进行排序和汇总,您可以在数据库中查找bigint

在 .NET 内部,TimeSpan 只不过是一个 long 值,它存储“滴答”的数量(参见 .NET source code for TimeSpan)以及一系列转换为秒、毫秒等的转换。

当您再次从数据库加载该值时,您可以根据存储在数据库中的报价重新创建 TimeSpan。你不会失去精确度。

您甚至可以对数据库值执行聚合函数(Min、Max、Avg、Sum),当您稍后在 C# 中加载该值时,您仍然会获得有效的 TimeSpan。

但是,如果您需要查询数据库以获取例如超过 5 分钟的值,则需要计算如何将 5 分钟表示为刻度。 在前面链接的源代码中,您会看到一秒钟有 10,000,000 个滴答声。所以这几乎不是火箭科学;)

【讨论】:

看来我不是唯一一个知道这一点的人:***.com/a/744929/64096【参考方案2】:

如果您确定您的 elapsedTime 将少于 24 小时,您可以更改

cmd.Parameters["@ElapsedTime"].Value = elapsedTime;

cmd.Parameters["@ElapsedTime"].Value = elapsedTime.ToString("hh\:mm\:ss\.ffff");

我不确定是否有另一种方法可以将时间跨度转换为 sql 时间。请注意,如果您的持续时间超过 24 小时,溢出将被截断。

【讨论】:

【参考方案3】:

在 SSMS 中进行了快速测试。我认为是你的计算不正确。不能有 84 秒,因为最大值是 59。

这不起作用,因为秒数不能超过 84。

declare @tim time(7)
set @tim = '00:01:84.9383728'
select @tim

这行得通..

declare @tim time(7)
set @tim = '00:01:59.9383728'
select @tim

【讨论】:

【参考方案4】:

为什么不在数据库中使用float 数据类型存储时间?如果您通常以秒和分钟的顺序进行测量,那么只需存储总秒数。如果您通常测量毫秒,则存储总毫秒。 “保持简单,但不要变得愚蠢。”

除非您的应用程序需要将时间存储为“X 月 X 天 X 小时 X 分钟 X.XX 秒”......我敢打赌这不太可能。

【讨论】:

以上是关于在 SQL Server 中插入经过的时间的主要内容,如果未能解决你的问题,请参考以下文章

SQL Server插入触发器改进

检索 ODBC 表并插入 SQL Server CE 数据库

SQL Server Nvarchar(最大值)

如何在 SQL Server 2005 中进行更新插入(更新或插入)

仅允许 SQL Server 插入的当前日期/时间

sql server 中如何插入一条时间记录