How to use UPDATE statement inside a SELECT statement in SQL Server trigger?

w51jfk4q  于 2023-03-17  发布在  SQL Server
关注(0)|答案(1)|浏览(226)

Following is my trigger that I'm trying to do both insert and update based on the inserted record. I'm writing this INSERT trigger in my EVN_UPTIME table( db fiddle ) when rows get inserted the trigger will sort out the records and insert into ACT_UPTIME table.

CREATE TABLE [dbo].[EVN_UPTIME]
(
    [id] [int] IDENTITY(1,1) NOT NULL,
    [tag_name] [varchar](64) NULL,
    [tag_id] [int] NULL,
    [tag_value] [varchar](64) NULL,
    [tag_timestamp] [datetime] NULL,
    [tag_quality] [int] NULL,

    PRIMARY KEY CLUSTERED ([id] ASC)
                WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, 
                      IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, 
                      ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO

INSERT INTO [dbo].[EVN_UPTIME] (tag_name, tag_id, tag_value, tag_timestamp, tag_quality)
VALUES ('AB.HT_CTMS.Prgm_SKB.f_encoder_IS_moving',9,0,'2023-03-10 13:01:37.033',192)

INSERT INTO [dbo].[EVN_UPTIME] (tag_name, tag_id, tag_value, tag_timestamp, tag_quality)
VALUES ('AB.HT_CTMS.Prgm_ALO2.f_encoder_IS_moving',11,1,'2023-03-10 13:02:00.617',192)

INSERT INTO [dbo].[EVN_UPTIME] (tag_name, tag_id, tag_value, tag_timestamp, tag_quality)
VALUES ('AB.HT_CTMS.Prgm_ALO2.f_encoder_IS_moving',11,0,'2023-03-10 13:02:29.317',192)

INSERT INTO [dbo].[EVN_UPTIME] (tag_name, tag_id, tag_value, tag_timestamp, tag_quality)
VALUES ('AB.HT_CTMS.Prgm_SKB.f_encoder_IS_moving',9,1,'2023-03-10 13:02:52.733',192)

INSERT INTO [dbo].[EVN_UPTIME] (tag_name, tag_id, tag_value, tag_timestamp, tag_quality)
VALUES ('AB.HT_CTMS.Prgm_SKB.f_encoder_IS_moving',9,0,'2023-03-10 13:03:07.837',192)

INSERT INTO [dbo].[EVN_UPTIME] (tag_name, tag_id, tag_value, tag_timestamp, tag_quality)
VALUES ('AB.HT_CTMS.Prgm_SKB.f_encoder_IS_moving',9,1,'2023-03-10 13:03:08.320',192)

INSERT INTO [dbo].[EVN_UPTIME] (tag_name, tag_id, tag_value, tag_timestamp, tag_quality)
VALUES ('AB.CMM.Prgm_MainProgram.f_motor_start',13,0,'2023-03-10 13:04:11.203',192)

INSERT INTO [dbo].[EVN_UPTIME] (tag_name, tag_id, tag_value, tag_timestamp, tag_quality)
VALUES ('AB.HT_CTMS.Prgm_SKB.f_encoder_IS_moving',9,0,'2023-03-10 13:04:18.963',192)

INSERT INTO [dbo].[EVN_UPTIME] (tag_name, tag_id, tag_value, tag_timestamp, tag_quality)
VALUES ('AB.CMM.Prgm_MainProgram.f_motor_start',13,1,'2023-03-10 13:04:34.330',192)

INSERT INTO [dbo].[EVN_UPTIME] (tag_name, tag_id, tag_value, tag_timestamp, tag_quality)
VALUES ('AB.HT_CTMS.Prgm_ALO2.f_encoder_IS_moving',11,1,'2023-03-10 13:07:54.590',192)

INSERT INTO [dbo].[EVN_UPTIME] (tag_name, tag_id, tag_value, tag_timestamp, tag_quality)
VALUES ('AB.HT_CTMS.Prgm_SKB.f_encoder_IS_moving',9,1,'2023-03-10 13:08:19.947',192)

INSERT INTO [dbo].[EVN_UPTIME] (tag_name, tag_id, tag_value, tag_timestamp, tag_quality)
VALUES ('AB.HT_CTMS.Prgm_SKB.f_encoder_IS_moving',9,0,'2023-03-10 13:08:56.550',192)

INSERT INTO [dbo].[EVN_UPTIME] (tag_name, tag_id, tag_value, tag_timestamp, tag_quality)
VALUES ('AB.NOR_CTMS.Prgm_NORM4.d_auto_mode',4,0,'2023-03-10 13:09:22.817',192)

INSERT INTO [dbo].[EVN_UPTIME] (tag_name, tag_id, tag_value, tag_timestamp, tag_quality)
VALUES ('AB.CMM.Prgm_MainProgram.f_motor_start',13,0,'2023-03-10 13:13:29.127',192)

INSERT INTO [dbo].[EVN_UPTIME] (tag_name, tag_id, tag_value, tag_timestamp, tag_quality)
VALUES ('AB.CMM.Prgm_MainProgram.f_motor_start',13,1,'2023-03-10 13:13:40.457',192)

INSERT INTO [dbo].[EVN_UPTIME] (tag_name, tag_id, tag_value, tag_timestamp, tag_quality)
VALUES ('AB.CMM.Prgm_MainProgram.f_motor_start',13,0,'2023-03-10 13:13:45.477',192)
AFTER INSERT
AS
BEGIN
    INSERT INTO ACT_UPTIME(
        tag_id, 
        machine,
        down_start_time,
        down_end_time,
        total_downtime,
        create_user, 
        create_date
    )
    SELECT
        tag_id,
        CASE 
            WHEN tag_name = 'AB.NOR_CTMS.Prgm_NORM1.d_auto_mode'  THEN 'N1'     
            WHEN tag_name = 'AB.NOR_CTMS.Prgm_NORM2.d_auto_mode'  THEN 'N2'          
            WHEN tag_name = 'Fanuc.BS35X_SN002.AutoMode'  THEN 'N3'         
            WHEN tag_name = 'AB.NOR_CTMS.Prgm_NORM4.d_auto_mode'  THEN 'N4'        
            WHEN tag_name = 'AB.BS30_SN001.AUTO_MODE'  THEN 'N5'     
            WHEN tag_name = 'AB.BS45_SN006.AUTO_MODE'  THEN 'N6'    
            WHEN tag_name = 'Fanuc.BS75_SN011.AutoMode'  THEN 'N8'          
            WHEN tag_name = 'AB.HT_CTMS.Prgm_SKB.f_encoder_IS_moving'  THEN 'SKB'         
            WHEN tag_name = 'AB.HT_CTMS.Prgm_ALO1.f_encoder_IS_moving'  THEN 'ALO-1'        
            WHEN tag_name = 'AB.HT_CTMS.Prgm_ALO2.f_encoder_IS_moving'  THEN 'ALO-2'     
            WHEN tag_name = 'AB.HT_CTMS.Prgm_ALO3.f_encoder_IS_moving'  THEN 'ALO-3'    
            WHEN tag_name = 'AB.CMM.Prgm_MainProgram.f_motor_start'  THEN 'CMM'          
            WHEN tag_name = 'AB.HT_CTMS.Prgm_ELPH.f_encoder_IS_moving'  THEN 'ELPH'         
            WHEN tag_name = 'AB.HT_CTMS.Prgm_HT1.f_encoder_IS_moving'  THEN 'HT-1'        
            WHEN tag_name = 'AB.HT_CTMS.Prgm_HT2.f_encoder_IS_moving'  THEN 'HT-2'     
        END AS machine, 
        CASE 
            WHEN tag_value = 0 THEN tag_timestamp
        END AS down_start_time,
        CASE 
            WHEN tag_value = 1 THEN tag_timestamp
        END AS down_end_time,
        0,
        SUSER_NAME(),
        GETDATE()
    FROM
        inserted
END

Following figure is what I'm getting based on the above trigger, DB fiddle

Now getting to the question, the following figure is my end goal. DB Fiddle

Following is the code for the SQL trigger what I was able to try out and got stuck at currently while figuring out my end goal.

AFTER INSERT
AS
BEGIN
    INSERT INTO ACT_UPTIME(
        tag_id, 
        machine,
        down_start_time,
        down_end_time,
        total_downtime,
        create_user, 
        create_date
    )
    SELECT
        tag_id,
        CASE WHEN tag_name = 'AB.NOR_CTMS.Prgm_NORM1.d_auto_mode'  THEN 'N1'     
       WHEN tag_name = 'AB.NOR_CTMS.Prgm_NORM2.d_auto_mode'  THEN 'N2'          
       WHEN tag_name = 'Fanuc.BS35X_SN002.AutoMode'  THEN 'N3'         
       WHEN tag_name = 'AB.NOR_CTMS.Prgm_NORM4.d_auto_mode'  THEN 'N4'        
       WHEN tag_name = 'AB.BS30_SN001.AUTO_MODE'  THEN 'N5'     
       WHEN tag_name = 'AB.BS45_SN006.AUTO_MODE'  THEN 'N6'    
       WHEN tag_name = 'Fanuc.BS75_SN011.AutoMode'  THEN 'N8'          
       WHEN tag_name = 'AB.HT_CTMS.Prgm_SKB.f_encoder_IS_moving'  THEN 'SKB'         
       WHEN tag_name = 'AB.HT_CTMS.Prgm_ALO1.f_encoder_IS_moving'  THEN 'ALO-1'        
       WHEN tag_name = 'AB.HT_CTMS.Prgm_ALO2.f_encoder_IS_moving'  THEN 'ALO-2'     
       WHEN tag_name = 'AB.HT_CTMS.Prgm_ALO3.f_encoder_IS_moving'  THEN 'ALO-3'    
       WHEN tag_name = 'AB.CMM.Prgm_MainProgram.f_motor_start'  THEN 'CMM'          
       WHEN tag_name = 'AB.HT_CTMS.Prgm_ELPH.f_encoder_IS_moving'  THEN 'ELPH'         
       WHEN tag_name = 'AB.HT_CTMS.Prgm_HT1.f_encoder_IS_moving'  THEN 'HT-1'        
       WHEN tag_name = 'AB.HT_CTMS.Prgm_HT2.f_encoder_IS_moving'  THEN 'HT-2'     
        END AS machine, 
        CASE WHEN tag_value = 0 THEN tag_timestamp
        END AS down_start_time,
        UPDATE [MES_DEV].[dbo].[ACT_UPTIME] 
        SET down_end_time =  
        (CASE WHEN tag_value = 1 THEN tag_timestamp)
        
        END,
        0,
        SUSER_NAME(),
        GETDATE()
    FROM
        inserted
END

Here I was trying to write a UPDATE statement inside a CASE statement when the trigger sees the INSERT record with the tag_value of '1' then the record with same tag_id which has NULLdown_end_time value will be updated with the time, and finally calculate the total_downtime by getting the difference of the down_start_time and down_end_time times.

Somehow I'm getting bunch of syntax errors in SQL Server and not able to save the trigger.

What am I doing wrong here trying to write the UPDATE statement inside a CASE statement of the INSERT trigger? Is it not possible to do?

9jyewag0

9jyewag01#

I was able to find the answer with the hints/clues provided by @Larnu in the comments section. Much appreciated for diverting me towards the correct side.

Here's to anyone finds it interesting :

BEGIN
    INSERT INTO ACT_UPTIME(
        tag_id, 
        machine,
        down_start_time,
        total_downtime,
        create_user, 
        create_date
    )
    SELECT
        tag_id,
        CASE WHEN tag_name = 'AB.NOR_CTMS.Prgm_NORM1.d_auto_mode'  THEN 'N1'     
       WHEN tag_name = 'AB.NOR_CTMS.Prgm_NORM2.d_auto_mode'  THEN 'N2'          
       WHEN tag_name = 'Fanuc.BS35X_SN002.AutoMode'  THEN 'N3'         
       WHEN tag_name = 'AB.NOR_CTMS.Prgm_NORM4.d_auto_mode'  THEN 'N4'        
       WHEN tag_name = 'AB.BS30_SN001.AUTO_MODE'  THEN 'N5'     
       WHEN tag_name = 'AB.BS45_SN006.AUTO_MODE'  THEN 'N6'    
       WHEN tag_name = 'Fanuc.BS75_SN011.AutoMode'  THEN 'N8'          
       WHEN tag_name = 'AB.HT_CTMS.Prgm_SKB.f_encoder_IS_moving'  THEN 'SKB'         
       WHEN tag_name = 'AB.HT_CTMS.Prgm_ALO1.f_encoder_IS_moving'  THEN 'ALO-1'        
       WHEN tag_name = 'AB.HT_CTMS.Prgm_ALO2.f_encoder_IS_moving'  THEN 'ALO-2'     
       WHEN tag_name = 'AB.HT_CTMS.Prgm_ALO3.f_encoder_IS_moving'  THEN 'ALO-3'    
       WHEN tag_name = 'AB.CMM.Prgm_MainProgram.f_motor_start'  THEN 'CMM'          
       WHEN tag_name = 'AB.HT_CTMS.Prgm_ELPH.f_encoder_IS_moving'  THEN 'ELPH'         
       WHEN tag_name = 'AB.HT_CTMS.Prgm_HT1.f_encoder_IS_moving'  THEN 'HT-1'        
       WHEN tag_name = 'AB.HT_CTMS.Prgm_HT2.f_encoder_IS_moving'  THEN 'HT-2'     
        END AS machine, 
        CASE WHEN tag_value = 0 THEN tag_timestamp
        END AS down_start_time,
        0,
        SUSER_NAME(),
        GETDATE()
    FROM
        inserted;

    UPDATE A
    SET A.down_end_time =
    CASE WHEN i.tag_value = 1 
        THEN i.tag_timestamp
        END
    FROM ACT_UPTIME A INNER JOIN inserted i ON A.tag_id = i.tag_id
    WHERE A.tag_id = i.tag_id AND A.down_end_time IS NULL;
        
END

相关问题