如何在 mysql 的游标循环中只发生一次插入

how to have insertion happen only once in a cursor loop in mysql

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

如何修复我的代码,以便在没有 creating/firing 触发器的情况下不会将新广告系列插入 table。我希望它在此过程中工作。

Table代码

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//

一种解决方案是使用:

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 现在为假,因此 insert...select 将插入零行。