PROCEDURE E CURSORI IN MYSQL WB

di il
7 risposte

PROCEDURE E CURSORI IN MYSQL WB

Buongiorno. Ho una table di nome DIPART (che contiene informazioni relative ai dipartimenti) e due attributi: NUM_DIPART che è il numero del dipartimento (chiave) e NUM_DIP che è il numero di dipendenti per ogni dipartimento.

Dovrei scrivere ora una procedura sql che controlla il valore di NUM_DIP per ogni dipartimento della table, e se è maggiore di 3 lo si decrementa di un valore x dato in input alla procedura, se è minore di 3, lo si incrementa dello stesso valore.

Ho provato a scrivere la procedura, ma non funziona perchè è come se non riuscisse a leggere i valori delle tuple sui due attributi indicati. Facendo infatti diverse select interne alla procedura, ciò che risulta è che num_dip (variabile interna alla procedura) risulta null, come se il cursore nella riga di FETCH non ritornasse il valore concreto che serve poi per la select NUM_DIP, o addirittura che proprio questa select, a prescindere dalla condizione where, restituisca tutti valori null. Vi prego aiutatemi.

In ogni caso, dopo l'esecuzione mi dice 0 rows affected, quindi a questo punto non entra nemmeno negli if.

Di sotto la procedura:

DELIMITER $$
CREATE PROCEDURE ModNumDip(IN VALORE INTEGER)
BEGIN
   DECLARE dip_id INT;
   DECLARE num_dip INT;
   DECLARE done INT DEFAULT FALSE;

   -- Dichiarazione del cursore per iterare sui dipartimenti
   DECLARE dip_cursor CURSOR FOR
       SELECT NUM_DIPART
       FROM DIPART;
    
    DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;
   
   -- Apertura del cursore
   OPEN dip_cursor;
   
   -- Loop per iterare sui dipartimenti
   dip_loop: LOOP
       FETCH dip_cursor INTO dip_id;
       -- Uscita dal loop se non ci sono più record
       
       IF done THEN
         LEAVE dip_loop;
       END IF;
        
       -- Aggiorna il numero di dipendenti per il dipartimento
      SELECT NUM_DIP INTO num_dip FROM DIPART WHERE NUM_DIPART=dip_id;
       
      IF (num_dip < 3) THEN
        UPDATE DIPART SET NUM_DIP = num_dip + VALORE WHERE NUM_DIPART=dip_id; ;
       ELSE 
        UPDATE DIPART SET NUM_DIP = num_dip - VALORE WHERE NUM_DIPART=dip_id;
      END IF;
      
   END LOOP;

   -- Chiusura del cursore
   CLOSE dip_cursor;
END $$
DELIMITER

CALL ModNumDip(5); 

7 Risposte

  • Re: PROCEDURE E CURSORI IN MYSQL WB

    A parte il fatto che la descrizione (incremento e decremento) è contraria a quanto scritto e che non controlli che i valori finali possano diventare negativi (che sarebbe assurdo), mi chiedo se tu non possa risolvere tutto con una sola UPDATE senza script

  • Re: PROCEDURE E CURSORI IN MYSQL WB

    14/02/2024 - oregon ha scritto:


    A parte il fatto che la descrizione (incremento e decremento) è contraria a quanto scritto e che non controlli che i valori finali possano diventare negativi (che sarebbe assurdo), mi chiedo se tu non possa risolvere tutto con una sola UPDATE senza script

    Si scusa, per quanto riguarda la descrizione adesso ho corretto. Per quanto riguarda i valori negativi non ho fatto il controllo perché non funzionando il resto, non ho implementato questo check. In ogni caso i dati sono pochi e ne sono a conoscenza, quindi ponendo per esempio 1 nella call, non vanno mai negativi i risultati. Il problema è che a me è stato espressamente chiesto di farlo tramite procedura.

  • Re: PROCEDURE E CURSORI IN MYSQL WB

    14/02/2024 - Davi0983878 ha scritto:


    IF (num_dip < 3) THEN
            UPDATE DIPART SET NUM_DIP = num_dip + VALORE ;
           ELSE 
            UPDATE DIPART SET NUM_DIP = num_dip - VALORE ;
          END IF;

    Guarda bene queste due UPDATE: non manca forse la clausola WHERE?

    Cosa fa una UPDATE senza clausola WHERE? Ti rispondo io: ti fa buttare via l'intera tabella e passare un bruttissimo quarto d'ora con il tuo superiore.

  • Re: PROCEDURE E CURSORI IN MYSQL WB

    14/02/2024 - SpiritoLibero ha scritto:


    14/02/2024 - Davi0983878 ha scritto:


    IF (num_dip < 3) THEN
            UPDATE DIPART SET NUM_DIP = num_dip + VALORE ;
           ELSE 
            UPDATE DIPART SET NUM_DIP = num_dip - VALORE ;
          END IF;

    Guarda bene queste due UPDATE: non manca forse la clausola WHERE?

    Cosa fa una UPDATE senza clausola WHERE? Ti rispondo io: ti fa buttare via l'intera tabella e passare un bruttissimo quarto d'ora con il tuo superiore.

    Si scusa hai ragione, l'ho portato nella query sopra per ottenere num_dip e non l'ho riscritto nelle due update. Ora ho aggiornato grazie. La situazione è comunque la stessa, perche è come se in num_dip ci sia già null e quindi non entrasse nemmeno nell'if

  • Re: PROCEDURE E CURSORI IN MYSQL WB

    DIIPART: NUM_DIPART; NUM_DIP 

    Cioè la tabelladipart ha numero dipartimento e.numero dipendenti

    Es.

    Dioartimento.   Dipendenti

    Abc.                           2

    Dfs.                           4

    Ecc…

    Se ho capito bene… questa:

    14/02/2024 - Davi0983878 ha scritto:


    SELECT NUM_DIP INTO num_dip FROM DIPART WHERE NUM_DIPART=dip_id;

    A che ti serve?

  • Re: PROCEDURE E CURSORI IN MYSQL WB

    14/02/2024 - sihsandrea ha scritto:


    A che ti serve?

    A poter fare la if subito dopo…

    @Davi0983878

    Giusto per completezza, visto che ad occhio non vedo errori, puoi postare la struttura della tabella DIPART?

  • Re: PROCEDURE E CURSORI IN MYSQL WB

    14/02/2024 - SpiritoLibero ha scritto:


    14/02/2024 - sihsandrea ha scritto:


    A che ti serve?

    A poter fare la if subito dopo…

    @Davi0983878

    Giusto per completezza, visto che ad occhio non vedo errori, puoi postare la struttura della tabella DIPART?

    Ciao esatto mi serve a quello! Anche io stavo impazzendo perché non riuscivo a trovare l'errore, ma alla fine ci sono arrivato a furia di provare ed era una cosa banalissima… MySQL è case INSENSITIVE, quindi sostanzialmente confondeva la variabile interna num_dip con l'attributo NUM_DIP e quindi si annullavano le tuple relative a tale attributo. Ho risolto semplicemente cambiando il nome della variabile interna! Grazie mille comunque a tutti del supporto!

Devi accedere o registrarti per scrivere nel forum
7 risposte