SQL Server触发器插入具有不同行集的多个行

时间:2017-09-28 12:29:16

标签: sql-server stored-procedures triggers

如何使用SQL Server触发器将带有时间序列行的表转换为基于列的?

时间序列源表variable_table

---------------------------------------------------
timestamp    var             property        value
---------------------------------------------------
1506598200   A01_NetOrder    49              10.0
1506598200   A01_NetOrder    50               3.5
1506598200   A01_NetRec      49              20.0
1506598200   A01_NetRec      50               4.0
--------------------------------------------------

将在目标表中插入多行并带有触发器。

目的地表var_column_table

---------------------------------------------------------
timestamp      loc       property    NetOrder     NetRec
---------------------------------------------------------
1506598200    A01        49          10.0         20.0
1506598200    A01        50           3.5          4.0
---------------------------------------------------------

触发工作

ALTER trigger [dbo].[rowColInsert]
ON [dbo].[variable_table]
AFTER INSERT 
AS
BEGIN
    SET NOCOUNT ON;

    declare @timestamp int
    declare @val varchar(125)
    declare @var varchar(125)
    declare @loc varchar(125)
    declare @col varchar(125)
    declare @cal int
    declare @sql varchar(max)

    select @timestamp = (select timestamp from inserted)
    select @var = (select var from inserted)
    select @property = (select property from inserted)
    select @value = (select value from inserted)

    select 

    select 
        @loc = (select left(@var, (select charindex('_', @var,0))-1))

    if exists (select timestamp from var_column_table where timestamp = @time)
    begin
        select @sql = 'update var_column_table set ' + @col + '=' + cast(@value as varchar)
        exec(@sql)
    end
    else
    begin
        select @sql = 'insert into var_column_table (timestamp, loc, property' + @col + ') values (' + cast(@timestamp as varchar) + ',' + cast(@loc as varchar) + ',' + cast(@property as varchar) + ','+ cast(@value as varchar) + ')'
        exec(@sql)
    end
 end

请告知工作以获得所需的结果。注意:inserted表有多条记录。

修改

1)variable_table中的var有多个前缀,如:V01,V02,V03 ......

1 个答案:

答案 0 :(得分:1)

您需要在merge语句中访问inserted表。你的触发器:

     ALTER trigger [dbo].[rowColInsert]
        ON [dbo].[variable_table]
        AFTER INSERT 
        AS
        BEGIN
            SET NOCOUNT ON;

           MERGE var_column_table AS TARGET 
    USING
    (
    SELECT timestamp
    ,substring(var,0,charindex('_',var)) as loc
    , i1.property
    ,i1.value as NetOrder
    ,i2.value as NetRec
    FROM inserted i1 
    inner join inserted i2 on i1.timestamp = i2.timestamp and i1.property=i2.property
WHERE i1.property like '%NetOrder%' AND i2.property like '%NetRec%'
    ) AS SOURCE (timestamp, loc, property, NetOrder, NetRec)
    ON TARGET.timestamp = SOURCE.timestamp AND TARGET.property = SOURCE.property
    WHEN MATCHED THEN UPDATE
    SET
    TARGET.NetOrder = SOURCE.NetOrder,
    TARGET.NetRec = SOURCE.NetRec 
    WHEN NOT MATCHED THEN INSERT (timestamp, loc, property, NetOrder, NetRec)
    VALUES (source.timestamp, source.loc, source.property, source.NetOrder, source.NetRec);
         end

请测试它是否有效。基本上'inserted'表包含触发器触发时插入的所有行。您可以使用merge语句来执行upsert逻辑。