Autore Topic: Sqlite, eliminare record corelati a catena  (Letto 2710 volte)

Offline Golia

  • Senatore Gambero
  • ******
  • Post: 1.298
  • no xe mai massa tardi
    • Mostra profilo
Sqlite, eliminare record corelati a catena
« il: 20 Gennaio 2010, 00:31:00 »
Ciao a tutti,
Stò creando un piccolo database con sqlite, mi trovo questo problema.
Con MySQL creando una tabella così:
Codice: [Seleziona]

CREATE TABLE contatti(
idcontatto INT auto_increment,
idfornitore INT NOT NULL,
contatto varchar(40),  
notecontatto varchar(80),
PRIMARY KEY idcontatto (idcontatto),
INDEX fornitori_key (idfornitore),
FOREIGN KEY (idfornitore) REFERENCES fornitori(idfornitore)
ON DELETE CASCADE
ON UPDATE CASCADE)
TYPE=InnoDB;

..cancellando il fornitore mi cancella in automatico tutti i contatti legati a quel id fornitore.

Come si fà con sqlite?

Ciao grazie

Offline compnoprofit

  • Gamberetto
  • *
  • Post: 11
    • Mostra profilo
    • http://softisteria.org
Re: Sqlite, eliminare record corelati a catena
« Risposta #1 il: 20 Gennaio 2010, 10:13:39 »
Credo si possa fare con i triggers:
CREATE TRIGGER contatti before delete on fornitori
Una volta li utilizzai in un test, se nessuno ti risponde quando vado a casa cerco di recuperare il codice e lo posto

Offline Golia

  • Senatore Gambero
  • ******
  • Post: 1.298
  • no xe mai massa tardi
    • Mostra profilo
Re: Sqlite, eliminare record corelati a catena
« Risposta #2 il: 21 Gennaio 2010, 16:40:59 »
Grazie, aspetto il tuo codice, intanto mi documento

Offline compnoprofit

  • Gamberetto
  • *
  • Post: 11
    • Mostra profilo
    • http://softisteria.org
Re: Sqlite, eliminare record corelati a catena
« Risposta #3 il: 21 Gennaio 2010, 21:22:15 »
Nel mio programma che iniziai a far con codeblocks e poi abbandonai facevo cosí:

dalla linea di comando mi creo il database
SQLITE3 prezzario.db3

creo le tabelle:

Codice: [Seleziona]
CREATE TABLE [costi] (
[id_costo] INTEGER  PRIMARY KEY NOT NULL,
[cod_costo] VARCHAR(40) UNIQUE NOT NULL,
[descr_costo] VARCHAR(255)  NOT NULL,
[costo_unit] REAL NOT NULL,
[genere] VARCHAR(40)  NOT NULL,
[unmis] VARCHAR(40)  NOT NULL
);

CREATE TABLE [analisi] (
[id_an] INTEGER  NOT NULL PRIMARY KEY,
[articolo] VARCHAR(255) NOT NULL,
[cod_costo] VARCHAR(40) NOT NULL,
[resa] REAL,
[costo] REAL
);


creo i triggers rispettivamente sulle operazioni di insert, update e delete:

Codice: [Seleziona]
CREATE TRIGGER edit_analisi before insert on analisi
for each row
begin
select case
when
(
(new.cod_costo is not null)
   and
 (
  ((select cod_costo from costi where
    cod_costo =new.cod_costo) is null)
)
)
then raise(abort,'violacion integridad')
end;
end;

CREATE TRIGGER upd_analisi before update on analisi

for each row begin
select case
when
(
((select cod_costo from costi where
 cod_costo = new.cod_costo) is null)
)
then raise(abort,'violacion integridad')
end;
end;

CREATE TRIGGER delete_costo before delete on costi

for each row begin
select case
when
((select cod_costo from analisi
 where cod_costo = old.cod_costo) is not null)
 then raise(abort,'violacion integridad')
 end;
 end;


Spero che possa esserti utile

Offline Golia

  • Senatore Gambero
  • ******
  • Post: 1.298
  • no xe mai massa tardi
    • Mostra profilo
Re: Sqlite, eliminare record corelati a catena
« Risposta #4 il: 22 Gennaio 2010, 00:37:39 »
Grazie del codice che mi hai mandato.

Allora ho inserito i trigger come mi hai consigliato, ho provato proprio creando le tabelle da te descritte.
Quello che volevo fare io è che eliminando un "costo" mi elimini tutte le "analisi" che sono legate da "cod_costo".
Ho provato a cancellare un record di costo, ma non me lo permette, neanche se cancello tutti i record di analisi... :-?
Magari ci riprovo domani...
Il concetto è giusto? Cioè serve a fare questa azione il trigger delete?

Ciao grazie

Offline Ceskho

  • Amministratore
  • Senatore Gambero
  • *****
  • Post: 3.778
  • Vi Veri Veniversum Vivus Vici
    • Mostra profilo
    • Pagina Personale
Re: Sqlite, eliminare record corelati a catena
« Risposta #5 il: 22 Gennaio 2010, 00:43:57 »
@ compnoprofit

Ho editato il tuo messaggio per renderlo più leggibile...ricorda di usare i tag code...grazie..;-)

Offline compnoprofit

  • Gamberetto
  • *
  • Post: 11
    • Mostra profilo
    • http://softisteria.org
Re: Sqlite, eliminare record corelati a catena
« Risposta #6 il: 22 Gennaio 2010, 11:37:03 »
grazie Ceskho
@Golia
prova con
Codice: [Seleziona]

CREATE TRIGGER cancellatutto
BEFORE DELETE ON costi

FOR EACH ROW BEGIN

    DELETE from analisi WHERE cod_costo = OLD.cod_costo;

END;


Cosí cancellando un record di costi si cancellano tutte le analisi con lo stesso cod_costo.
Il trigger precedente delete_costo fa l'opposto di quello che mi hai chiesto, ossia impedisce cancellare un costo se sono presenti analisi che lo utilizzano, quindi dovrai eliminarlo dal db, però è bene conoscerlo potrá servirti per altre tabelle.

Offline Golia

  • Senatore Gambero
  • ******
  • Post: 1.298
  • no xe mai massa tardi
    • Mostra profilo
Re: Sqlite, eliminare record corelati a catena
« Risposta #7 il: 26 Gennaio 2010, 23:19:13 »
Ti ringrazio, mi hai indicato la strada giusta  :D
Ho fatto così
Codice: [Seleziona]
  sql = "CREATE TABLE clienti ("
    sql &= " idcliente INTEGER NOT NULL PRIMARY KEY,"
    sql &= " 'nome' varchar(20) DEFAULT NULL"   
    sql &= " );"
hTable = $sqlitehConn.EXEC(sql)

  sql = "CREATE TABLE preventivi ("
  sql &= " idpreventivo INTEGER NOT NULL PRIMARY KEY,"
  sql &= " idcliente_preventivi INTEGER,"
  sql &= " 'descrizione' varchar(250) DEFAULT NULL"   
  sql &= " CONSTRAINT controllo_preventivi REFERENCES clienti(idcliente) ON DELETE CASCADE"
  sql &= " );"
hTable = $sqlitehConn.EXEC(sql)


  sql = "CREATE trigger controllo_preventivi"
  sql &= " before DELETE ON clienti"
  sql &= " FOR EACH row begin"
  sql &= " DELETE FROM preventivi WHERE idcliente_preventivi = old.idcliente;"
  sql &= " END ;"
hTable = $sqlitehConn.EXEC(sql)


Ciao grazie

Offline compnoprofit

  • Gamberetto
  • *
  • Post: 11
    • Mostra profilo
    • http://softisteria.org
Re: Sqlite, eliminare record corelati a catena
« Risposta #8 il: 29 Gennaio 2010, 09:22:35 »
Ti ringrazio, mi hai indicato la strada giusta  :D
Ciao grazie

Non c'è di che, sono contento che ti sia servito, io prenderó nota del tuo codice per implementare in Gambas la sentenza sqlite, mi servirá.
Ciao