PDA

View Full Version : [MySql] Un aiutino su semplice trigger che non funziona :-/


Trigger2009
22-06-2009, 16:27
Ciao,
sono nuovo di quì...il mio compagno di progetto mi ha detto di provare a chiedere quà perchè c'è un sacco di gente preparata e disponibile.
Insieme stiamo concludendo un progetto per un esame universitario e devo cacciarci dentro qualche triggerino e qualche piccola stored procedure.
Questa mattina ho studiato da solo l'argomento ed ho creato il mio primo trigger ma ho qualche problema a farlo andare

Il nostro progetto tratta un sistema di aste online ispirato ad e-bay (ovviamente è un esempio giocattolo) e quì se volete potete vedere lo schema fisico del mio database anche se per questo trigger non credo serva in quanto entrano in gioco solo 2 tabelle: http://www.siatec.net/andrea/uni/db/fisico.jpg

PREMESSA: Come su e-bay, dopo che un utente ha acquistato un oggetto rilascia un feedback al venditore relativo all'oggetto comprato, poi quando il venditore riceve il feedback ne rilascia a sua volta uno all'acquirente. Per questo motivo le tabelle dei feedback mettono in relazione un utente con un altro utente e con una determinata inserzione.
Stessa cosa vale per i messaggi che, come su e-bay, mettono in relazione un utente con un altro utente ed una determinata inserzione (perchè un messaggio è relativo ad una certa inserzione).

Queste sono le strutture delle due tabelle che entrano in gioco nel mio trigger:


TABELLA FEEDBAKVENDITORE:
mysql> describe feedbackvenditore\g
+---------------+--------------------------------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+---------------+--------------------------------------+------+-----+---------+-------+
| Id_Oggetto | int(11) | NO | PRI | NULL | |
| Id_Venditore | varchar(20) | NO | | NULL | |
| Id_Acquirente | varchar(20) | NO | | NULL | |
| Feedback | enum('Positivo','Neutro','Negativo') | NO | | NULL | |
| Commento | varchar(255) | YES | | NULL | |
+---------------+--------------------------------------+------+-----+---------+-------+

TABELLA MESSAGGIO:
mysql> describe messaggio\g
+--------------+-------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+--------------+-------------+------+-----+---------+----------------+
| Id_Messaggio | int(11) | NO | PRI | NULL | auto_increment |
| Mitt | varchar(20) | NO | | NULL | |
| Dest | varchar(20) | NO | MUL | NULL | |
| Id_Oggetto | int(11) | NO | | NULL | |
| Data | datetime | NO | | NULL | |
| Testo | text | NO | | NULL | |
+--------------+-------------+------+-----+---------+----------------+



Detto questo io voglio realizzare un trigger sulla tabella FEEDBACKVENDITORE che si comporti così:
Quando viene inserito un recordo nella tabella FEEDBACKVENDITORE (quindi logicamente quando un venditore riceve un feedback da un acquirente relativo ad una certa inserzione) viene mandato un messaggio al venditore che gli dice che l'utente in questione gli ha rilasciato un feedback per quel prodoto e che è pregato di rilasciare a sua volta il feedback a quell'utente

Per fare questa cosa quando viene inserito un record nella tabella FEEDBACKVENDITORE il trigger deve inserire un record nella tabella MESSAGGIO così fatto:

Il campo Mitt di MESSAGGIO deve contenere il valore del campo Id_Acquirente del nuovo record inserito nella tabella FEEDBACKVENDITORE

Il campo Dest di MESSAGGIO deve contenere il valore del campo Id_Venditore del nuovo record inserito nella tabella FEEDBACKVENDITORE

Il campo Id_Oggetto di MESSAGGIO deve contenere il campo Id_Oggetto del nuovo record inserito nella tabella FEEDBACKVENDITORE

Il campo Data di MESSAGGIO deve contenere data ed ora attuali

Il campo Testo di MESSAGGIO deve contenere il testo di avviso dell'avvenuta ricezione di un feedback

ed il campo IdMessaggio di MESSAGGIO deve essere NULL perchè tanto è la chiave della tabella ed è auto increment quindi ci pensa il dbms a metterciil valore giusto.

Questo è il trigger che ho creato io, dite che va bene? ci sono errori sintattici? Come devo darlo in pasto al mio DB per farlo funzionare? Altra cosa...è molto commentato ma non sò come si mettano i commenti ai trigger per MySql....

Poi sotto ho riportato anche la versione senza commenti per darla in pasto a MySql...


/*Crea un trigger che inserisce un record nella cartella MESSAGGIO quando un venditore lascia un feedback ad un acquirente */

DELIMITER $$ // Nuovo deliminatore

CREATE TRIGGER Avvisa_FeedBack_da_Venditore_Trg
BEFORE INSERT ON feedbackVenditore // L'evento che fà partire il trigger è un inserimento nella tabella feedbackVenditore
FOR EACH ROW // e deve essere eseguito una volta sola per ogni riga

BEGIN // Inizia il codice da eseguire del trigger

DECLARE mittente VARCHAR(20); // Dichiara la variabile mittente per contenere una stringa di al più 20 caratteri
DECLARE destinatario VARCHAR(20); // Dichiara la variabile destinatario per contnere una stringa di 20 caratteri
DECLARE id_oggetto INTEGER; // Dichiara la variabile id_oggetto di tipo integer
DECLARE data_e_ora datetime; // Dichiara la variabile data e ora che conterrà la data e l'ora
DECLARE testo_messaggio TEXT; // Dichiara la variabile testo per contenere il testo del messaggio di tipo text


/** Ora metto dentro la variabile mittente il valore del campo Id_Venditore del nuovo record inserito nella tabella
FEEDBACKVENDITORE */

SELECT Id_Acquirente // Seleziona il campo Id_Acquirente
INTO mittente // Copiane il contenuto dentro la variabile mittente
FROM FeedbackVenditore // il campo Id_Acquirente selezionato si riferisce alla tabella FeedbackVenditore
WHERE Id_Oggetto = NEW Id_Oggetto; // dove ci si riferisce al nuovo record inserito nella tabella FeedbackVenditore


/** Ora metto dentro la variabile destinatario il valore del campo Id_Acquirente del nuovo record inserito nella
tabella FEEDBACKVENDITORE */

SELECT Id_Venditore // Seleziona il campo Id_Venditore
INTO destinatario // Copiane il contenuto dentro la variabile destinatario
FROM FeedbackVenditore // il campo Id_Venditore selezionato si riferisce alla tabella FeedbackVenditore
WHERE Id_Oggetto = NEW Id_Oggetto; // dove ci si riferisce al nuovo record inserito nella tabella FeedbackVenditore


/** Ora metto dentro la variabile id_oggetto il valore del campo Id_Oggetto del nuovo record inserito nella tabella
FEEDBACKVENDITORE */

SELECT Id_Oggetto // Seleziona il campo Id_Oggetto
INTO id_oggetto // Copiane il contenuto dentro la variabile id_oggetto
FROM FeedbackVenditore // il campo Id_oggetto selezionato si riferisce alla tabella FeedbackVenditore
WHERE Id_Oggetto = NEW Id_Oggetto; // dove ci si riferisce al nuovo record inserito nella tabella FeedbackVenditore


/** Ora metto dentro la variabile data_e_ora la data e l'ora corrente */

SET data_e_ora = CURRENTE_TIMESTAMP(); // Metto dentro la variabile la data ed il tempo


/** Ora metto dentro la variabile testo_messaggio il testo del messaggio da inviare all'utente venditore che ha
appena ricevuto un feedback da un acquirente relativo ad un determinato oggetto*/

SET testo_messaggio = CONCAT('Un acquirente avente username: ', Id_Acquirente, ' ti ha lasciato un feedback relativo alla vendita di un oggetto avente id: ', id_oggetto, 'Sei pregato di rilasciare a tua volta il feedback a questo acquirente');


/** Ora devo inserire nella tabella MESSAGGIO il record che rappresenta il messaggio che deve essere ricevuto dal
venditore che ha appena ricevuto un feedback nella tabella FEEDBACKVENDITORE */

INSERT INTO messaggio (Id_Messaggio, Mitt, Dest, Id_Oggetto, Data, Testo)
VALUES(NULL, mittente, destinatario, id_oggetto, data_e_ora, testo_messaggio);

END$$ // Fine codice del trigger


Con i commenti non lo accetta neanche MySql...eccovi la versione priva di commenti e l'errore che mi dà:


mmm se provo a mandare in esecuzione la versione senza commenti del trigger mi dà un errore che non capisco, questo è quello che dò in pasto al mio MySql


DELIMITER $$

CREATE TRIGGER Avvisa_FeedBack_da_Venditore_Trg
BEFORE INSERT ON feedbackVenditore
FOR EACH ROW

BEGIN

DECLARE mittente VARCHAR(20);
DECLARE destinatario VARCHAR(20);
DECLARE id_oggetto INTEGER;
DECLARE data_e_ora datetime;
DECLARE testo_messaggio TEXT;


SELECT Id_Acquirente
INTO mittente
FROM FeedbackVenditore
WHERE Id_Oggetto = NEW Id_Oggetto;


SELECT Id_Venditore
INTO destinatario
FROM FeedbackVenditore
WHERE Id_Oggetto = NEW Id_Oggetto;


SELECT Id_Oggetto
INTO id_oggetto
FROM FeedbackVenditore
WHERE Id_Oggetto = NEW Id_Oggetto;


SET data_e_ora = CURRENTE_TIMESTAMP();



SET testo_messaggio = CONCAT('Un acquirente avente username: ', Id_Acquirente, ' ti ha lasciato un feedback relativo alla vendita di un oggetto avente id: ', id_oggetto, 'Sei pregato di rilasciare a tua volta il feedback a questo acquirente');


INSERT INTO messaggio (Id_Messaggio, Mitt, Dest, Id_Oggetto, Data, Testo)
VALUES(NULL, mittente, destinatario, id_oggetto, data_e_ora, testo_messaggio);

END$$


e mi dà il seguente errore:


ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version
for the right syntax to use near 'Id_Oggetto;


SELECT Id_Venditore
INTO destinatario
FROM FeedbackVen' at line 17


Oddio sono disperato...non capisco da cosa sia causato...please help me
:confused: :dhò: :(

Per favore dateci una mano che non ne riusciamo a venire a capo e tra pochi giorni dobbiamo consegnare il proggettone.

Grazie a tutti

CwNd
22-06-2009, 19:40
Ciao, tre cosettine veloci che ho visto:

-La sintassi corretta per utilizzare la parola chiave New è new.NomeCampo

-I commenti vanno scritti nella forma /*Commento*/, non mi pare si possano usare altre forme

-Non capisco perchè nella query di insert non usi direttamente i valori prendi dalla variabile New.campo e te li vai a tirare fuori con delle query..

Trigger2009
22-06-2009, 19:54
Ciao, tre cosettine veloci che ho visto:

-La sintassi corretta per utilizzare la parola chiave New è new.NomeCampo

-I commenti vanno scritti nella forma /*Commento*/, non mi pare si possano usare altre forme

-Non capisco perchè nella query di insert non usi direttamente i valori prendi dalla bariabile New.campo e te li vai a tirare fuori con delle query..

Si la prima cosa che mi avevi detto l'avevo trovata nel frattempo ma continuo ad avere qualche problemuccio, ora il mio trigger che avevo modificato è questo:


DELIMITER $$

CREATE TRIGGER AvvisoTrigger
BEFORE INSERT ON feedbackVenditore
FOR EACH ROW

BEGIN

DECLARE mittente VARCHAR(20);
DECLARE destinatario VARCHAR(20);
DECLARE id_oggetto INTEGER;
DECLARE data_e_ora datetime;
DECLARE testo_messaggio TEXT;


SELECT FeedbackVenditore.Id_Acquirente
INTO mittente
FROM FeedbackVenditore
WHERE Id_Oggetto = NEW.Id_Oggetto;


SELECT FeedbackVenditore.Id_Venditore
INTO destinatario
FROM FeedbackVenditore
WHERE Id_Oggetto = NEW.Id_Oggetto;


SELECT FeedbackVenditore.Id_Oggetto
INTO id_oggetto
FROM FeedbackVenditore
WHERE Id_Oggetto = NEW.Id_Oggetto;


SET data_e_ora = CURRENT_TIMESTAMP();

SET testo_messaggio = CONCAT('Un acquirente avente username: ', Id_Acquirente, ' ti ha lasciato un feedback relativo alla vendita di un oggetto avente id: ', id_oggetto, 'Sei pregato di rilasciare a tua volta il feedback a questo acquirente');

INSERT INTO messaggio (Id_Messaggio, Mitt, Dest, Id_Oggetto, Data, Testo)
VALUES(NULL, mittente, destinatario, id_oggetto, data_e_ora, testo_messaggio);

END$$


Però il problema è che quando tento di fare l'inserimento di un record dentro la tabella FEEDBACKVENDITORI non me lo fa fare e MySql Query Broswer mi dice:
Unknown column 'Id_Acquirente' in 'field list'

Perchè? Forse ho pasticciato troppo con quelle variabili?
Te in pratica che dici di fare? di metterci direttamente i valori da New.campo?

Stò impazzendo e non ci stò più con la testa perchè è da questa mattina che ci smanetto (mi sono letto un intero libro in inglese sulle stored procedure in un giorno...)...non è che mi potresti dare una manina a risolvere? E' molto importante se no non posso consegnare il progetto :cry:

Grazie

CwNd
22-06-2009, 20:07
hai provato a mettere al posto di:

SET testo_messaggio = CONCAT('Un acquirente avente username: ', Id_Acquirente, ' ti ha lasciato un feedback relativo alla vendita di un oggetto avente id: ', id_oggetto, 'Sei pregato di rilasciare a tua volta il feedback a questo acquirente');



SET testo_messaggio = CONCAT('Un acquirente avente username: ', mittente, ' ti ha lasciato un feedback relativo alla vendita di un oggetto avente id: ', id_oggetto, 'Sei pregato di rilasciare a tua volta il feedback a questo acquirente');


oppure

SET testo_messaggio = CONCAT('Un acquirente avente username: ', new.Id_Acquirente, ' ti ha lasciato un feedback relativo alla vendita di un oggetto avente id: ', id_oggetto, 'Sei pregato di rilasciare a tua volta il feedback a questo acquirente');

?

comunque si, io direi di usare direttamente i valori che hai inserito, attarverso l'operatore new, diverrebbe molto più veloce l'esecuzione :)

Trigger2009
22-06-2009, 20:30
GODOOOOO ORA FUNZIONA !!!

Grazie 1000, ma secondo te come mai non prendeva usando le variabili? Forse erano sbagliati i tipi dati alle variabili?

Grazie
Andrea

CwNd
22-06-2009, 23:31
Di niente, se non ci si aiuta tra compagni :) eheh :asd:

Sinceramente non so bene perchè non funzionava, ma credo che trattandosi di un trigger di tipo before, i dati che tu andavi a prelevare con le varie select non erano ancora stati inseriti :)

Ciao :)

Trigger2009
23-06-2009, 00:21
Di niente, se non ci si aiuta tra compagni :) eheh :asd:

Sinceramente non so bene perchè non funzionava, ma credo che trattandosi di un trigger di tipo before, i dati che tu andavi a prelevare con le varie select non erano ancora stati inseriti :)

Ciao :)

e se al posto del before ci avessi messi un after? dici che funzionava?

Casomai se trovo il tempo provo :D

CwNd
23-06-2009, 10:40
e se al posto del before ci avessi messi un after? dici che funzionava?

Casomai se trovo il tempo provo :D

Sinceramente non saprei, ma tieni conto che l'approccio attuale è quello più performante :)

Trigger2009
23-06-2009, 11:04
Ok...ieri notte poi ho creato un altro trigger per conto mio...praticamente è un trigger che elimina i record dalla tabella FOTO quando una trattativa è conclusa (ovvero quando entrambi gli utenti hanno rilasciato il rispettivo feedback) così da risparmiare spazio su disco togliendo record ormai inutili e migliorare le performance del DB....

Ora però mi è venuto in mente che mi servirebbe un altro triggerino ma non ho molte idee su come realizzarlo...

Praticamente ho 2 tabelle: FEEDBACKVENDITORE che contiene i feedback lasciati ai venditori dagli acquirenti e FEEDBACKACQUIRENTE che contiene i feedback lasciati dai venditori agli acquirenti.

Quando un utente compra un oggetto il venditore glielo spedisce, quando l'acquirente lo riceve lascia un feedback al venditore (viene inserito un record nella tabella FEEDBACKVENDITORE, si attiva il trigger di cui ho parlato nel primo post che manda un messaggio al venditore pregandolo di dare il suo feedback all'acquirente), a questo punto il venditore lascia il proprio feedback all'acquirente inserendo un record nella tabella FEEDBACKACQUIRENTE.

Questa è la modalità standard di una vendita...

Però potrebbe succedere che un venditore distratto lasci un feedback all'acquirente prima di averlo ricevuto...ecco non voglio che succeda questa cosa (è diverso da ebay ma mi devo inventare qualche stronzata per far contento la proff)

Come posso fare a creare un trigger che si comporta nel seguente modo:
Se il venditore prova a lasciare un feedback ad un utente (relativo ad una certa inserzione) ma non ha ancora ricevuto il feedback per quella inserzione, il record non viene inserito e viene lanciato un messaggio di errore

Le due tabelle sono fatte così:


mysql> describe feedbackVenditore;
+---------------+--------------------------------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+---------------+--------------------------------------+------+-----+---------+-------+
| Id_Oggetto | int(11) | NO | PRI | NULL | |
| Id_Venditore | varchar(20) | NO | | NULL | |
| Id_Acquirente | varchar(20) | NO | | NULL | |
| Feedback | enum('Positivo','Neutro','Negativo') | NO | | NULL | |
| Commento | varchar(255) | YES | | NULL | |
+---------------+--------------------------------------+------+-----+---------+-------+
5 rows in set (0.26 sec)

+---------------+--------------------------------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+---------------+--------------------------------------+------+-----+---------+-------+
| Id_Oggetto | int(11) | NO | PRI | NULL | |
| Id_Acquirente | varchar(20) | NO | | NULL | |
| Id_Venditore | varchar(20) | NO | | NULL | |
| Feedback | enum('Positivo','Neutro','Negativo') | NO | | NULL | |
| Commento | varchar(255) | YES | | NULL | |
+---------------+--------------------------------------+------+-----+---------+-------+



Qualche idea?

CwNd
23-06-2009, 11:15
Beh innanzitutto non ho capito perchè usi tabella distinte, quando potresti usarne una con l'ausilio di un campo che funga da discriminante :)
Successivamente non hai specificato come fai a controllare che un utente abbia ricevuto effettivamente l'oggetto!

Trigger2009
23-06-2009, 11:22
Beh innanzitutto non ho capito perchè usi tabella distinte, quando potresti usarne una con l'ausilio di un campo che funga da discriminante :)
Successivamente non hai specificato come fai a controllare che un utente abbia ricevuto effettivamente l'oggetto!

mmm considera cmq che non è un'applicazione concreta ma si tratta di un "progeto giocattolo" per un esame...non dovrà essere implementato per un'applicazione.

Sul fatto delle 2 tabelle...booo...questo esame si basa sull'ottimizzazione del progetto dell'esame dell'anno scorso...l'anno scorso l'avevo fatto così ed oggi me lo ritrovo...in qualche modo lo avevo giustificato...credo per motivi di performance....
Nel senso che ogni tabella contiene fino a mezzo milione di record...se mettevo insieme le 2 tabelle dei FEEDBACK avrei avuto veramente tantissimi record in una sola tabella ed andando a fare le query per visualizzare i feedback dei venditori o quelli degli acqirenti avrei dovuto usare un campo in più nelle condizioni di WHERE riducendo ulteriormente le performance...allora ho pensato di tenerle logicamente separate e via...

L'utente ha ricevuto l'oggetto quando lascia il feedback al venditore...anche e-bay fa qualcosa del genere (nel senso che non c'è un vero controllo sull'effettivo arrivo della merce...almeno credo)...cmq questa è una complicazione in più non richiesta per l'esame...alla fine lo scopo del corso è smanettare e far vedere che sappiamo usare un po' tutti gli argomenti...non creare un programma reale

CwNd
23-06-2009, 11:32
Premesso che:

Mysql non disponse una una funzione per lanciare gli errori, a menochè non ti compili una UDF che trovi su internet percui l'unico modo che hai è richiamare una funzione che non esiste in modo che venga sollevato il relativo l'errore.
Oppure puoi scegliere utilizzare l'operatore LEAVE, in modo che il trigger venga bloccato, ma non verrebbe sollevato nessun errore.

potresti fare una roba del genere:


Codice di definizione del trigger all'evento before insert
/*Verifichi se l'acquirente ha rilasciato il feedback andando a contare se c'è un record nella tabella FeedBackAcquirente*/

SELECT COUNT(*) Into contatore FROM FeedbackAcquirente WHERE condizione che ti serve

/*Se il contatore è diverso da 1 vuol dire che non è stato ancora lasciato il feedback dal venditore percui lanciamo l'errore*/
IF contatore <> 1 THEN
CALL Operazione_non_permessa();


Ho pensato a una cosa del genere, effettivamente però non so se è adatta o meno al tuo scenario.

Trigger2009
23-06-2009, 11:49
mmm scusa se ti rompo ancora...

Seguendo le tue indicazioni stavo facendo così:


DELIMITER $$

CREATE TRIGGER Check_FeedBAck_Trg
BEFORE INSERT ON FeedbackAcquirente /* Esegue il trigger prima dell'inserzione di un record in FeedbackAcquirente */
FOR EACH ROW

BEGIN

DECLARE contatore INTEGER; /* Dichiaro una variabile contatore intera */

/* Mettre dentro contatore il numero di record presenti in FeedbackVenditore il cui campo Id_Oggetto ha lo stesso
valore del campo Id_Oggetto del record che si stà tentando di inserire in FeedbackAcquirente */

SELECT COUNT(*) INTO contatore FROM FeedbackVenditore WHERE NEW.Id_Oggetto = FeedBackVenditore.Id_Oggetto;

/* Se il contatore è diverso da 1 vuol dire che non è stato ancora lasciato il feedback dal venditore percui lanciamo
l'errore */

IF contatore <> 1 THEN
CALL Operazione_non_permessa()


Solo che...se contatore è diverso da 1, cosa intendi con CALL Operazione_non_permessa() ? dove deve essere definita? Allo stato attuale per me potrebbe anche semplicemente non inserire il record...come faccio a dirgli di non inserire il record nella tabella FEEDBACKACQUIRENTI se si verifica questa condizione?

Poi casomai per allungare un po' il brodo oltre a dirgli di non inserire il record qualora la condizione della if sia vera, potrei anche fargli mandare un messaggio privato al venditore che lo avverte dell'errore (come avevo fatto per il primo trigger)...ma per ora se riesci a farmi sapere come dirgli di non inserire il record va più che bene :)

Grazie

CwNd
23-06-2009, 13:54
Come ti ho scritto nel post precedente quella CALL server a fare in modo che venga sollevato un errore.
Se ti basta semplicemente rifiutare l'inserimento, sostituisci CALL Operazione_non_permessa(); con LEAVE;

Ciao ciao

Trigger2009
23-06-2009, 15:06
Come ti ho scritto nel post precedente quella CALL server a fare in modo che venga sollevato un errore.
Se ti basta semplicemente rifiutare l'inserimento, sostituisci CALL Operazione_non_permessa(); con LEAVE;

Ciao ciao

Ok ti ringrazio, poi provo.

Quindi se faccio CALL Operazione_non_permessa();
Operazione_non_permessa() sarebbe l'errore che viene sollevato? E' tipo un'eccezione?

Grazie
Andrea

CwNd
23-06-2009, 15:09
Ok ti ringrazio, poi provo.

Quindi se faccio CALL Operazione_non_permessa();
Operazione_non_permessa() sarebbe l'errore che viene sollevato? E' tipo un'eccezione?

Grazie
Andrea

Come ti ho scritto nel post precedente Mysql non dispone di una funzione built-in per lanciare errori e per ovviare a questa cosa puoi fare in due modi:

-Ti compili una UDT (ovvero una funziona scritta usando le Mysql API, in rete se ne trovano) apposita

-Richiami una funzione non esistente in modo che venga tirato l'errore.

Trigger2009
23-06-2009, 18:13
mmm strano non mi funziona in nessuno dei due modi:

Se gli dò in pasto:


DELIMITER $$

CREATE TRIGGER Check_FeedBack_Trg
BEFORE INSERT ON FeedbackAcquirente /* Esegue il trigger prima dell'inserzione di un record in FeedbackAcquirente */
FOR EACH ROW

BEGIN

DECLARE contatore INTEGER; /* Dichiaro una variabile contatore intera */

/* Mettre dentro contatore il numero di record presenti in FeedbackVenditore il cui campo Id_Oggetto ha lo stesso
valore del campo Id_Oggetto del record che si stà tentando di inserire in FeedbackAcquirente */

SELECT COUNT(*) INTO contatore FROM FeedbackVenditore WHERE NEW.Id_Oggetto = FeedBackVenditore.Id_Oggetto;

/* Se il contatore è diverso da 1 vuol dire che non è stato ancora lasciato il feedback dal venditore percui lanciamo
l'errore */

IF contatore <> 1 THEN
LEAVE;
END IF;

END$$


Mi dice:
You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ';
END IF;

END' at line 18

Se invece gli provo a fare eseguire questa versione:


DELIMITER $$

CREATE TRIGGER Check_FeedBack_Trg
BEFORE INSERT ON FeedbackAcquirente /* Esegue il trigger prima dell'inserzione di un record in FeedbackAcquirente */
FOR EACH ROW

BEGIN

DECLARE contatore INTEGER; /* Dichiaro una variabile contatore intera */

/* Mettre dentro contatore il numero di record presenti in FeedbackVenditore il cui campo Id_Oggetto ha lo stesso
valore del campo Id_Oggetto del record che si stà tentando di inserire in FeedbackAcquirente */

SELECT COUNT(*) INTO contatore FROM FeedbackVenditore WHERE NEW.Id_Oggetto = FeedBackVenditore.Id_Oggetto;

/* Se il contatore è diverso da 1 vuol dire che non è stato ancora lasciato il feedback dal venditore percui lanciamo
l'errore */

IF contatore <> 1 THEN
THEN CALL Operazione_non_permessa();
END IF;

END$$


Mi dà:
You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'THEN CALL Operazione_non_permessa();
END IF;

END' at line 18

Come mai? da che può dipendere?
mi ci stò impiccando...ho controllato anche sul manuale e la sintassi mi pare corretta...perchè va in errore? dai che ho quasi finito sto progetto del cavolo...

CwNd
23-06-2009, 23:09
Per il primo prova a fare così

DELIMITER $$

CREATE TRIGGER Check_FeedBack_Trg
BEFORE INSERT ON FeedbackAcquirente /* Esegue il trigger prima dell'inserzione di un record in FeedbackAcquirente */
FOR EACH ROW

trig:BEGIN

DECLARE contatore INTEGER; /* Dichiaro una variabile contatore intera */

/* Mettre dentro contatore il numero di record presenti in FeedbackVenditore il cui campo Id_Oggetto ha lo stesso
valore del campo Id_Oggetto del record che si stà tentando di inserire in FeedbackAcquirente */

SELECT COUNT(*) INTO contatore FROM FeedbackVenditore WHERE NEW.Id_Oggetto = FeedBackVenditore.Id_Oggetto;

/* Se il contatore è diverso da 1 vuol dire che non è stato ancora lasciato il feedback dal venditore percui lanciamo
l'errore */

IF contatore <> 1 THEN
LEAVE trig;
END IF;

END$$

Comunque nel secondo hai messo due THEN!

Ti ricordo che la differenza tra il primo e il secondo è che rispettivamente l'inserimento viene rifiutato senza nessun errore e che viene lanciato un errore al chiamante.

Trigger2009
24-06-2009, 22:43
Ti ringrazio...tra questa sera e domani mattina lo provo e ti faccio sapere se funziona...ora sono troppo distrutto...per lavoro oggi mi è toccato prendere due voli: Roma-Milano alle 7 del mattino per un cavolo corso di formazione e Milano-Roma...tornato adesso...ora non connetto :eek:

Evolevo anche studiare teoria per l'orale questa sera :cry:
E Sabato e Domenica devo iniziare questo lavoro del corso di formazione di oggi :cry: :cry: :cry:
E Martedi devo consegnare il progetto :cry: :cry: :cry: :cry: :cry: :cry: :cry:

E Mercoledi devo fare l'orale :cry: :cry: :cry: :cry: :cry: :cry: :cry:

Scusate4 lo sfogo :cry:

Trigger2009
24-06-2009, 23:58
DISPERAZIONE:

Quando provo a lanciare l'ultima versione del trigger che mi hai dato MySql Query Broswer mi dice:

This version of MySQL doesn't yet support 'multiple triggers with the same action time and event for one table'

ma non ci sono altri trigger sulla tabella FEEDBACKACQUIRENTI ed infatti se faccio show trigger mio dà solo questi 2: Elimina_Foto_Oggetti_Venduti_Trg e AvvisoTrigger

da che potrebbe dipendere?

Trigger2009
25-06-2009, 12:29
ed anche nel secondo esempio se tolgo il secondo then mi dice comunque:
This version of MySQL doesn't yet support 'multiple triggers with the same action time and event for one table'

come mai?

CwNd
25-06-2009, 12:51
A quanto pare non hai fatto il drop del trigger.
Scaricati sqlyog http://www.webyog.com/en/, che ti permette di lavorare senza troppi problemi.

Ciao

Trigger2009
25-06-2009, 13:09
Si ma io il drop del trigger l'ho fatto !!!

Se eseguo show trigger mi mostra solo gli altri 2 trigger creati precedentemente su altre tabelle e che funzionano perfettamente...che fa questo programma?

Trigger2009
25-06-2009, 13:36
Niente...anche sqlyog continua a dirmi la stessa cosa:

Error Code : 1235
This version of MySQL doesn't yet support 'multiple triggers with the same action time and event for one table'

Execution Time : 00:00:00:000
Transfer Time : 00:00:00:000
Total Time : 00:00:00:000


e continua a farmi vedere sempre i soliti due trigger chiamati rispettivamente AvvisaTrigger ed Elimina_Foto_Oggetti_Trg ma di questo nuovo trigger non c'è traccia...booo


EventTableTimingsql_modeDefiner
Elimina_Foto_Oggetti_Venduti_TrgINSERTfeedbackacquirenteBEFORESTRICT_TRANS_TABLES,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTIONroot@localhost
AvvisoTriggerINSERTfeedbackvenditoreBEFORESTRICT_TRANS_TABLES,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTIONroot@localhost


molto strano...

Ma se per risolvere questo problema non usassi un trigger ma imponessi un vincolo di integrità referenziale che mi fa inserire un record in FEEDBACKACQUIRENTE se è già presente il record in FEEDBACKVENDITORE relativo a quello specifico oggetto in FEEDBACKVENDITORE?

Anche perchè non posso sprecare la mia vita su sto trigger che non funziona... :muro: :muro: :muro: :muro:

CwNd
25-06-2009, 14:00
No ma il problema è che c'è un altro trigger con la stessa azione su quella tabella!

Trigger2009
25-06-2009, 14:06
No ma il problema è che c'è un altro trigger con la stessa azione su quella tabella!

è per quelloche è strano.

Facendo show triggers ecco il report:


/*Database: asteonline*/
------------------------

/*Trigger Information*/
-----------------------

TRIGGER Event TABLE Statement Timing Created sql_mode DEFINER character_set_client collation_connection DATABASE COLLATION
-------------------------------- ------ ------------------ ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ ------ ------- -------------------------------------------------------------- -------------- -------------------- -------------------- ------------------
Elimina_Foto_Oggetti_Venduti_Trg INSERT feedbackacquirente BEGIN BEFORE (NULL) STRICT_TRANS_TABLES,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION root@localhost utf8 utf8_general_ci latin1_swedish_ci

DELETE LOW_PRIORITY FROM foto WHERE foto.Id_Oggetto = NEW.Id_Oggetto;

END
AvvisoTrigger INSERT feedbackvenditore BEGIN BEFORE (NULL) STRICT_TRANS_TABLES,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION root@localhost utf8 utf8_general_ci latin1_swedish_ci


DECLARE data_e_ora DATETIME;
DECLARE testo_messaggio TEXT;


SET data_e_ora = CURRENT_TIMESTAMP();

SET testo_messaggio = CONCAT('Un acquirente avente username: ', new.Id_Acquirente, ' ti ha lasciato un feedback relativo alla vendita di un oggetto avente id: ', NEW.Id_Oggetto, 'Sei pregato di rilasciare a tua volta il feedback a questo acquirente');

INSERT INTO messaggio (Id_Messaggio, Mitt, Dest, Id_Oggetto, DATA, Tes


Questi sono gli unici 2 trigger dichiarati nel databse...

CwNd
25-06-2009, 20:53
Non so cosa dirti, io non sono mai incappato in questo errore, se non provando a definire due trigger sulla stessa tabella.