通过单个SQL查询插入多行时,处理BEFORE INSERT触发器中的多个行

时间:2017-09-21 22:09:49

标签: mysql sql-server triggers

我有 USER 表,其中包含" id"和"名称" columns.there是 PRODUCT 表,其中包含" id"和" user_id"列" USER_ID" column具有外键引用" id" USER 表中的列。当我使用具有相同user_id.like的单个sql查询插入多行时

INSERT INTO PRODUCT(id,user_id) VALUES(1,1),(2,1),(3,1),(4,1);

我想在插入触发器之前执行以下条件的句柄。

    在PRODUCT表上的
  • ,获取与插入记录具有相同外键引用的行数'外键。
  • 如果大于或等于3的数字。允许插入所有行。
  • 如果上述数字为0且尝试插入的原始数量大于或等于3,则允许插入所有原始数据。
  • 如果以上数字为0且尝试插入的原始数量小于3,则不允许插入所有原始数据并发送错误消息。

任何人都可以帮我编写BEFORE INSERT触发器来处理所有这些条件吗?

1 个答案:

答案 0 :(得分:1)

您可以使用左连接并对现有条目进行计数,以便在已存储3条或更多条记录时插入条目或插入至少有三条记录要插入用户ID。

    CREATE TABLE if not exists `product_46353892` (
      `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
      `user_id` int(11) DEFAULT NULL,
      PRIMARY KEY (`id`)
    ) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8;

    /* 
        truncate table to allow rerun of example 
        */
    truncate product_46353892 ;

    /* 
        example showing no inserts since there are only two records being inserted 
        and no previous records for this user_id
        */
    insert into product_46353892 ( id, user_id )
    select `new`.*
    -- , new_count.count new_count
    -- , old.count old_count
    from (
        select 1 id, 1 user_id
        union all
        select 2 id, 1 user_id
    ) `new`
    left join (
        select user_id, count(*) count from (
            select 1 id, 1 user_id
            union all
            select 2 id, 1 user_id
        ) new_group
        group by user_id
    ) new_count
    on `new`.user_id = new_count.user_id
    left join (
        select user_id, count(*) count from product_46353892 product
        group by user_id
    ) old
    on new.user_id = old.user_id
    where ( new_count.count >= 3 or old.count >= 3 or ( new_count.count + old.count ) >= 3 ) ;


    /* 
        this one works because there are three or more records in the insert
        */
    insert into product_46353892 ( id, user_id )
    select `new`.*
    from (
        select 3 id, 1 user_id
        union all
        select 4 id, 1 user_id
        union all 
        select 5 id, 1 user_id 
        union all 
        select 6 id, 1 user_id
    ) `new`
    left join (
        select user_id, count(*) count from (
            select 3 id, 1 user_id
            union all
            select 4 id, 1 user_id
            union all 
            select 5 id, 1 user_id 
            union all 
            select 6 id, 1 user_id
        ) new_group
        group by user_id
    ) new_count
    on `new`.user_id = new_count.user_id
    left join (
        select user_id, count(*) count from product_46353892 product
        group by user_id
    ) old
    on new.user_id = old.user_id
    where ( new_count.count >= 3 or old.count >= 3 or ( new_count.count + old.count ) >= 3 ) ;


    /* 
        this now works since there are already the required number of initial records stored 
        for this user_id
        */
    insert into product_46353892 ( id, user_id )
    select `new`.*
    -- , new_count.count new_count
    -- , old.count old_count
    from (
        select 1 id, 1 user_id
        union all
        select 2 id, 1 user_id
    ) `new`
    left join (
        select user_id, count(*) count from (
            select 1 id, 1 user_id
            union all
            select 2 id, 1 user_id
        ) new_group
        group by user_id
    ) new_count
    on `new`.user_id = new_count.user_id
    left join (
        select user_id, count(*) count from product_46353892 product
        group by user_id
    ) old
    on new.user_id = old.user_id
    where ( new_count.count >= 3 or old.count >= 3 or ( new_count.count + old.count ) >= 3 ) ;


    select * from product_46353892 ;

示例结果。请注意,在表中的用户ID已经有三条或更多条记录之后,第二个插入中插入了id,1和2的顺序。

id  user_id
3   1
4   1
5   1
6   1
1   1
2   1