update a table in trigger or a stored procedure generates the error code 1442

77 Views Asked by At

I have a database of 600 bottles (bottiglia), where I manage the sale to the public and the orders to supply the cellar.

I want each bottle to always have an availability (qta_disponibile) >= 2. Then, when I make a sale and the availability of the sold bottle drops to 2, an order of this bottle must automatically start.

Also if I sell to a new customer, this must be inserted in the 'Customer' (Cliente) table.

Finally, when I make an order, the availability of the bottle just ordered must be updated, adding the quantity ordered (qta_ordine).

This is the structure of my database:

-------------------------------------
-- Creazione della tabella Produttore
-------------------------------------

create table Produttore(
    p_iva bigint(11) unsigned not null,
    indirizzo varchar(40),
    num_telefono varchar(20),
    primary key(p_iva)
)
ENGINE=InnoDB;



-------------------------------------
-- Creazione della tabella Dipendente
------------------------------------- 

create table Dipendente(
    cf varchar(16) not null,
    nome varchar(100) not null,
    cognome varchar(100) not null,
    indirizzo varchar(200),
    num_telefono varchar(20),
    primary key(cf)
)
ENGINE=InnoDB;



----------------------------------
-- Creazione della tabella Cliente
----------------------------------

create table Cliente(
    cf varchar(16) not null,
    nome varchar(100) not null,
    cognome varchar(100) not null,
    indirizzo varchar(40),
    num_telefono varchar(20),
    primary key(cf)
)
ENGINE=InnoDB;



------------------------------------
-- Creazione della tabella Bottiglia
------------------------------------

create table Bottiglia(
    codice bigint(8) unsigned not null,
    tipo_bottiglia varchar(20) not null,
    produttore bigint(11) unsigned not null,
    annata year not null,
    qta_disponibile int not null,
    costo decimal(5, 2) not null,
    primary key(codice),
    foreign key(produttore) references Produttore(p_iva)
    on delete cascade
    on update cascade
)
ENGINE=InnoDB;



-------------------------------
-- Creazione della tabella Vino
------------------------------- 

create table Vino(
    codice bigint(8) unsigned,
    tipo_vino enum('rosso', 'bianco') not null,
    vitigno varchar(40) not null,
    gradazione_alcolica decimal (5, 2) not null,
    foreign key(codice) references Bottiglia(codice)
    on delete cascade
    on update cascade
)
ENGINE=InnoDB;



-----------------------------------
-- Creazione della tabella Spumante
-----------------------------------

create table Spumante(
    codice bigint(8) unsigned,
    metodo varchar(20) not null,
    vitigno varchar(40) not null,
    gradazione_alcolica decimal (5, 2) not null,
    foreign key(codice) references Bottiglia(codice)
    on delete cascade
    on update cascade
)
ENGINE=InnoDB;



-------------------------------------
-- Creazione della tabella Distillato
------------------------------------- 

create table Distillato(
     codice bigint(8) unsigned,
     tipologia varchar(10) not null,
     composizione varchar(20) not null,
     gradazione_alcolica decimal (5, 2) not null,
     foreign key(codice) references Bottiglia(codice)
     on delete cascade 
     on update cascade
)
ENGINE=InnoDB;



---------------------------------
-- Creazione della tabella Ordine
---------------------------------

create table Ordine(
    ID int(4) auto_increment,
    dipendente varchar(16),
    produttore bigint(11) unsigned,
    bottiglia bigint(8) unsigned,
    qta_ordine int,
    data date not null,
    primary key(ID),
    foreign key(dipendente) references Dipendente(cf)
    on delete cascade
    on update cascade,
    foreign key(produttore) references Produttore(p_iva)
    on delete cascade
    on update cascade,
    foreign key(bottiglia) references Bottiglia(codice)
    on delete cascade
    on update cascade
)
ENGINE=InnoDB;



----------------------------------
-- Creazione della tabella Vendita
----------------------------------

create table Vendita(
    ID_vendita int(4) auto_increment,
    bottiglia bigint(8) unsigned,
    cliente varchar(16),
    data date,
    qta_venduta int,
    costo_tot decimal (6, 2),
    primary key(ID_vendita),
    foreign key(bottiglia) references Bottiglia(codice)
    on delete cascade
    on update cascade,
    foreign key(cliente) references Cliente(cf)
    on delete cascade
    on update cascade
)
ENGINE=InnoDB;

COMMIT;

I tried using triggers and stored procedures, like this:

drop procedure if exists update_qtaDisponibile;
delimiter $$
create procedure update_qtaDisponibile(in bottigliaCod bigint(8), in qtaVenduta int)
begin
    update bottiglia
    set qta_disponibile = greatest(qta_disponibile - qtaVenduta, 0)
    where codice = bottigliaCod;
    
    if (select qta_disponibile from bottiglia where codice = bottigliaCod) < 2 then
        insert into ordine(dipendente, produttore, bottiglia, qta_ordine, data)
        values(
                (select cf from dipendente where cf = 'auto_order'),
                (select produttore from bottiglia where codice = bottigliaCod),
                bottigliaCod,
                1,
                current_date());
    end if;
end $$
delimiter ;

Trigger for the sales:

drop trigger if exists Before_Vendita;
delimiter $$
create trigger Before_Vendita
before insert on vendita
for each row
begin
    declare var int;
    set var = round((rand() * (20 - 1)) + 1);
    call update_qtaDisponibile(new.bottiglia, new.qta_venduta);
    
    if not exists (select 1 from cliente where cf = new.cliente) then
        insert into cliente(cf, nome, cognome, indirizzo, num_telefono)
        values (new.cliente, concat('nome_cliente_', var), concat('cognome_cliente_', var), concat('via_cliente_', var), concat('+39 ', lpad(floor(rand() * 10000000000), 10, '3')));
    end if;
end $$
delimiter ;

Trigger for the orders:

drop trigger if exists After_Ordine;
delimiter $$
create trigger After_Ordine
after insert on Ordine
for each row
begin 
    update bottiglia
    set qta_disponibile = qta_disponibile + new.qta_ordine
    where codice = new.bottiglia;
end $$
delimiter ;

But when I try to sell a bottle that has qta_disponibilita = 2, I get this error:

Error Code: 1442. Can't update table 'bottiglia' in stored function/trigger because it is already used by statement which invoked this stored function/trigger.

How can I do it?

0

There are 0 best solutions below