PDA

View Full Version : Problema SQL



Bakaras
24th February 2009, 16:31
Un cliente ci ha chiesto di cancellare settimanalmente dal db tutti i record con data inserimento passata da almeno 2 anni, e fin qui nulla da dire, getdate, datediff etc etc.
Il problema nasce con le relazioni:

http://img410.imageshack.us/img410/3748/relazioni2.jpg

La tabella da cui partire è C_account, e si deve portare dietro nella delete tutti i record collegati nelle tabelle indicate.
Ora, posto che fare tutte le delete a mano partendo dalle tabelle child è un bagno di sangue ( considerato anche che è una cosa da fare settimanalmente...) e che sono costretto a lavorare su un prestigioso sql server 7, c'è qualcuno in grado di aiutarmi ?

grazie in anticipo.

Mosaik
24th February 2009, 16:50
Stored procedur e dentro le delete..
Passi la data alle stored e lei fa tutto altra soluzione non ne vedo :)

Tanek
24th February 2009, 16:52
Scusami, ma se metti on delete cascade sui vari vincoli di integrità referenziale?

(ovvio che non è sempre fattibile questa soluzione, per non smazzarsi delete che non si vogliono fare, però te la suggerisco come easiest e fastest :P )

Bakaras
24th February 2009, 16:54
Scusami, ma se metti on delete cascade sui vari vincoli di integrità referenziale?

eh, non l'ho mai usata e sinceramente non sò se c'è su sql server 7 .

need help QQ

Tanek
24th February 2009, 16:57
E' come dire che, quando cancelli una riga che viene referenziata, invece di beccarti un errore di integrità referenziale, propaghi la delete su tutti i figli di quella tabella.

Primo link che ho trovato:
http://publib.boulder.ibm.com/infocenter/idshelp/v10/index.jsp?topic=/com.ibm.sqls.doc/sqls292.htm

Use the ON DELETE CASCADE option to specify whether you want rows deleted in a child table when corresponding rows are deleted in the parent table. If you do not specify cascading deletes, the default behavior of the database server prevents you from deleting data in a table if other tables reference it.

If you specify this option, later when you delete a row in the parent table, the database server also deletes any rows associated with that row (foreign keys) in a child table. The principal advantage to the cascading-deletes feature is that it allows you to reduce the quantity of SQL statements you need to perform delete actions.

Tunnel
24th February 2009, 17:03
Concordo per la stored da schedulare alle 23.30 tipo

Bakaras
24th February 2009, 17:06
E' come dire che, quando cancelli una riga che viene referenziata, invece di beccarti un errore di integrità referenziale, propaghi la delete su tutti i figli di quella tabella.

Primo link che ho trovato:
http://publib.boulder.ibm.com/infocenter/idshelp/v10/index.jsp?topic=/com.ibm.sqls.doc/sqls292.htm

Use the ON DELETE CASCADE option to specify whether you want rows deleted in a child table when corresponding rows are deleted in the parent table. If you do not specify cascading deletes, the default behavior of the database server prevents you from deleting data in a table if other tables reference it.

If you specify this option, later when you delete a row in the parent table, the database server also deletes any rows associated with that row (foreign keys) in a child table. The principal advantage to the cascading-deletes feature is that it allows you to reduce the quantity of SQL statements you need to perform delete actions.


Ok, diciamo che questo è pacifico ( anche se non ho idea di come usarla ma questo lo trovo).
Il problema è che ci sono diverse relazioni ( come vedi dal diagramma)

C_account è la tabella primaria, e ha diversi child, tra cui c'è anche c_curriculum, che ha a sua volta dei child che hanno anche loro dei child...

dò le dimissioni?

QQ

Bakaras
24th February 2009, 17:09
E aggiungo, dal link si evince che on delete cascade è una opzione da settare al momento della creazione della tabella e dei vincoli, cosa che non ho idea se è stata fatta, visto che è un db che ho ereditato.

Tanek
24th February 2009, 17:32
Beh certo quella clausola la metti alla creazione della constraint (e quindi per sulle tue tabelle sicuramente non c'è), ma ovviamente puoi fare le alter table sulle varie constraints (o al massimo drop/create), così le metti tutte con la clausola "on delete cascade" (anche quelle dei figli dei figli).

A me sembra la soluzione più veloce e facile, vedi tu se non intacca troppo l'integrità dei dati (qualcuno fa una delete su C_ACCOUNT e ti deleta altri N record, ovviamente non è che questa clausola è riservata alla tua procedura).

Tunnel
24th February 2009, 17:43
Sarò io che son stupido e nabbo ma mi sembra più semplice passare tramite un cursore

Bakaras
24th February 2009, 17:53
le soluzioni proposte sono entrambe complicate, le mie competenze di sql sono poco + che sufficienti, al livello di query semplici , join, etc etc.
mai scritto una stored procedure, mai trattato con relazioni o vincoli.
Grazie a tutti e due cmq.

Tanek
24th February 2009, 18:28
Ma cosa usi per accedere al db? Sicuro nello strumento che usi c'è una interfaccia per modificare tabelle e constraint se non ti ricordi/sai la sintassi SQL! Non è difficile, ma è una modifica alle tabelle e non una query.
Se vuoi fare una query devi per forza farti uno scriptone in cui dentro ne fai N in cui vai a fare le N delete sulle tabelle figlie (ovviamente prima le figlie delle figlie).

Qualcosa del tipo:
DELETE FROM C_ANAGRAFICA_SAS WHERE ACCOUNTID IN (SELECT ACCOUNTID FROM C_ACCOUNT WHERE *blabliblu del cliente*);
DELETE FROM C_ANAGRAFICA_RTI WHERE ACCOUNTID IN (SELECT ACCOUNTID FROM C_ACCOUNT WHERE *blabliblu del cliente*);
[...]
[per ultimo]
DELETE FROM C_ACCOUNT WHERE *blabliblu del cliente*;
COMMIT;

Bakaras
24th February 2009, 18:40
Ti sipego perchè vorrei evitare le alter table sulle relazioni.
Il database è parte ( ovviamente ) di un applicativo web based già esistente, dove ci sono già N pagine che fanno operazioni di insert, update, delete su record e tabelle.
Questo applicativo non è stato realizzato da me, e non ho uno straccio di documentazione , è piuttosto vasto ( le tabelle che vedi solo solo una parte ) e sono sicuro che se tocco qualcosa nelle relazioni sputtano tutto, secondo la ben nota legge informatica che dice " se qualcosa può andare male, lo farà".
QUeste cancellazioni sono una richiesta del cliente esterna all'applicativo, uno svecchiamento dei dati ; inoltre c'è da considerare il fatto che da quel che dice il tipo, le relazioni non sono complete perchè mancano almeno 3 tabelle ai vincoli di integrita ( con C_curriculum) e non si sà perchè non sono state realizzate anch'esse; considerazione corretta da parte sue che avanza dubbi sulla integrità del db e dei dati, ma ha messo in un mare di merda me che da una parte devo g4estire sto benedetto svecchiamento, dall'altro fare un analisi che riporti il perchè ste tabelle non sono vincolate e come fare per ripristinare i vincoli.
Da qui "temo" che la soluzione meno impattante sia quella di scrivere una stored procedure con dentro le query delete.

-.-

Warbarbie
24th February 2009, 18:43
Ma schedulare procedure di delete che ti partono il sesto giorno alle 23:55 non puoi?

Mosaik
24th February 2009, 18:46
Vai di stored infatti :confused:
La puoi fare pure senza paramentri visto che avendo sempre i 2 anni come discriminante il calcolo glielo fai fare internamente :D

Ogni volta che vuole fare pulizia prende e la lancia e fa tutto lei :D