【问题标题】:Should I use a TSQL trigger add records to an insert?我应该使用 TSQL 触发器将记录添加到插入中吗?
【发布时间】:2018-10-23 19:35:20
【问题描述】:

我们通过抓取工具的日志文件来记录有关工厂工具使用情况的数据。它们都有自己的格式,但一般来说,这些工具都会生成可以轻松转换为这种格式的数据:

MachineID StartTime DurationSeconds 操作 1 2018-10-22 01:30:00 60 钻 1 2018-10-22 01:31:00 60 钻头 1 2018-10-22 01:59:59 7202 钻头

在一小时内有多个记录是可以的。

这种形式的数据使分析变得繁琐,因为我们需要按一小时分组报告数据(例如,按开始时间四舍五入到小时的分组来报告每小时利用率)。这对于无限的持续时间是不可能的。我们当前的代码(在 .net 中)将上述日志文件记录映射到数据库,如下所示:

MachineID StartTime DurationSeconds 操作 1 2018-10-22 01:30:00 60 钻 1 2018-10-22 01:31:00 60 钻头 1 2018-10-22 01:59:59 1 钻 1 2018-10-22 02:00:00 3600 钻头 1 2018-10-22 03:00:00 3600 钻头 1 2018-10-22 04:00:00 1 钻

要在我们当前的系统中正确处理这件事有点棘手,我宁愿不向供应商指定这一点,并且让每个人都正确处理。让他们只写他们的“原始”开始/持续时间数据对每个人来说都会更容易。

如何使用触发器将常规(开始/持续时间)日志数据转换为我们想要的分块数据?似乎触发器可以迭代 DurationSeconds 和触发器中的块数据。

或者,我猜他们可以将原始数据写入一个表,我可以读取数据并将分块数据写入另一个表。

触发器似乎是一个更干净的解决方案。

【问题讨论】:

  • 由于您有以秒为单位的开始和持续时间,我认为从长远来看,计算列会产生更少的悲伤。
  • 触发器想法的问题在于,当触发器触发时,您不能保证在一组中获取所有行。 OTOH,您可以处理您获得的内容,然后在需要时添加新行,或者如果您已经添加了现有行,则更新它。
  • 您可以(大部分)使用 CLR 触发器重用现有的 .net 代码。
  • @RyanB。我不确定计算列有什么帮助。这样的列不会在需要时添加行。
  • @user1443098 你是什么意思我会得到所有的行?我不受限制,我必须在一个小时内将所有数据放在一行中。我们的许多工具运行时间都很短。我们分析的查询在我们的分块表上进行分组,按小时四舍五入。 (我更新了例子)

标签: sql-server tsql triggers


【解决方案1】:

我使用了一个存储过程:

ALTER PROCEDURE [dbo].[AddEquipmentUtilization] 
    @id_equip INT,
    @start_time DateTime,
    @job_seconds INT     
AS
BEGIN
    SET NOCOUNT ON;

    declare @min int;
    declare @sec int ;
    declare @sec_in_hour int;
    declare @sec_to_add int;

    --Write chunks of data to the table in pieces upto the #of seconds left in the hour
    WHILE @job_seconds > 0
        begin 

            -- Number of seconds left in current hour (partial hour OK)
            set @min = DATEPART(minute,@start_time);
            set @sec = DATEPART(second,@start_time);
            set @sec_in_hour = (59-@min)*60 + 60-@sec

            -- Add everything left in hour or the full hour  
            if @job_seconds < @sec_in_hour
                set @sec_to_add = @job_seconds
            else
                set @sec_to_add = @sec_in_hour

            insert into Test (StartTime,Seconds,Id) Values (@start_time,@sec_to_add,@id_equip)

            -- Invariant: add/subtract sec_to_add
            set @start_time = DateAdd(second,@sec_to_add,@start_time)
            set @job_seconds= @job_seconds-@sec_to_add
        end
END

【讨论】:

    猜你喜欢
    • 2023-01-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-07-20
    • 1970-01-01
    • 1970-01-01
    • 2013-06-11
    相关资源
    最近更新 更多