【问题标题】:how to have insertion happen only once in a cursor loop in mysql如何在mysql的游标循环中只发生一次插入
【发布时间】:2021-12-14 00:55:00
【问题描述】:

此过程获取品牌名称并将其与产品表中的品牌名称相匹配,然后创建一个广告系列。 当我使用产品表中不存在的品牌名称输入调用此过程 BrandNameCampaign 时,它仍在创建活动。我知道这是因为我将插入查询保留在循环之外,它正在检查 camp_c 游标是否具有空值。 但是,如果我将查询放在光标的重复循环中,它会生成一个错误代码:1062 duplicate entry 'x' (x is an int) for key 'campaign.PRIMARY'。

如何修复我的代码,以便在不创建/触发触发器的情况下不会将新广告系列插入表中。我希望它在这个过程中工作。

表格代码

create table Product (
    ProductID int not null,
    ProductType varchar (20) not null,
    PackageType varchar(20) not null, 
    YearProduced int not null,
    Price float not null,
    Brand varchar(255) not null,
    PRIMARY KEY (ProductID)
) 

create table Campaign (
    CampaignID int not null,
    CampaignStartDate date not null,
    CampaignEndDate date,
    PRIMARY KEY (CampaignID)
) 
create table DiscountDetails (
    ProductID int not null,
    CampaignID int not null,
    MembershipLevel varchar(20) not null, 
    Discount int not null,
    primary key (ProductID, CampaignID, MembershipLevel),
    foreign key (ProductID) references Product (ProductID),
    foreign key (CampaignID) references Campaign (CampaignID)
) 

程序代码

create procedure BrandNameCampaign (in brandname varchar(50))
    begin
    declare v_finished int default 0;
    declare prod_id int;
    declare newcampid int;
    declare camp_brand varchar(255);
    declare camp_c cursor for
        select productid, brand
        from product
        where brandname = brand
        order by price desc limit 5;
        
    declare continue handler for not found set v_finished = 1;
    
    SELECT 
        MAX(CampaignID)
    INTO newcampid FROM
        campaign;
    set newcampid = 1 + newcampid;    
    
    insert  into `Campaign`(`CampaignID`,`CampaignStartDate`,`CampaignEndDate`) values 
    (newcampid,date_add(curdate(), interval 4 week), date_add( curdate(), interval 8 week));
    
     -- working with cursor
    open camp_c;
    repeat
        fetch camp_c into prod_id, camp_brand;
    if not (v_finished = 1) then
        insert into discountdetails values (prod_id, newcampid, 'S', 20);
        insert into discountdetails values (prod_id, newcampid, 'G', 30);
        insert into discountdetails values (prod_id, newcampid, 'P', 40);
    end if;
    until v_finished
    end repeat;
    close camp_c;
    end//

【问题讨论】:

    标签: mysql mysql-workbench


    【解决方案1】:

    一种解决方案是使用:

    insert ignore into `Campaign` ...
    

    ignore 表示如果插入导致重复键或其他类型的错误,则不会生成错误。

    另一种解决方案可能是使用布尔变量:

    declare v_do_insert tinyint(1) default true;
    
    ...
    
    repeat
      insert  into `Campaign`(`CampaignID`,`CampaignStartDate`,`CampaignEndDate`) 
      select newcampid, date_add(curdate(), interval 4 week), date_add( curdate(), interval 8 week)
      from dual where v_do_insert=true;
    
      set v_do_insert = false;
    
      ...
    until v_finished
    end repeat; 
    

    在此示例中,insert...select 将在第一次循环中插入一行,但随后在循环的后续迭代中,v_do_insert 现在为 false,因此 insert...select 将插入零行。

    【讨论】:

    • 两者都有效,尽管我觉得后者比忽略选项更安全。您能否就忽略选项提出一些想法。
    • ignore 的一个缺点是它会忽略重复键之外的其他类型的错误。
    猜你喜欢
    • 1970-01-01
    • 2013-07-27
    • 1970-01-01
    • 2015-05-10
    • 2016-06-29
    • 2022-01-20
    • 1970-01-01
    • 1970-01-01
    • 2015-04-19
    相关资源
    最近更新 更多