View Full Version : [SQL] INSERT or UPDATE
sto sviluppando un modulo per joomla e mi trovo per la prima volta davanti a questo tipo di problema:
è possibile (in SQL) eseguire una query di inserimento se non esiste una certa tupla oppure eseguire un update in caso contrario?
mi spiego meglio, io dovrei inserire una tupla che contiene come campi un ID ed una stringa, ora, visto che io non so se questo ID è gia in uso vorrei che se lo fosse la nuova stringa andasse ad aggiornare quella gia esistente.
se non dovesse essere possibile non sapreste fornirmi un metodo alternativo?
così sui due piedi mi viene in mente di fare un "SELECT id FROM tabella where id=quello_che_mi_interessa"
poi tramite php controllo il risultato ed in caso di esito positivo eseguo un UPDATE, altrimenti un INSERT.
consigli?
cdimauro
07-11-2009, 15:11
Firebird è un engine che ti offre un'istruzione che esegue un'insert se il record non esiste, o un update se c'è già. Non so come sono messi gli altri engine SQL.
Eventualmente per quelli a cui manca uno strumento del genere lo si può implementare facilmente con delle stored procedure.
tutto risolto.
ho utilizzato questa espressione che a dire il vero nemmeno avevo mai sentito nominare, probabilmente è molto poco pubblicizzata:
ecco l'intera istruzione:
$query="INSERT INTO #__kthumb VALUES('".$value."', '".$_FILES['image']['name']."')
ON DUPLICATE KEY UPDATE thumb = '".$_FILES['image']['name']."';";
per quanto riguarda firebird, il problema è che, siccome sto sviluppando su joomla, non posso fare a meno di utilizzare MySQL ma grazie lo stesso per la gritta.
sto informando mi giusto adesso su questo firebird, noto che memorizza i dati in un file di testo, questo potrebbe essere interessante.
Firebird è un engine che ti offre un'istruzione che esegue un'insert se il record non esiste, o un update se c'è già. Non so come sono messi gli altri engine SQL.
Eventualmente per quelli a cui manca uno strumento del genere lo si può implementare facilmente con delle stored procedure.
Si su MySQL è l'unica alternativa :cool:
cdimauro
07-11-2009, 17:34
tutto risolto.
ho utilizzato questa espressione che a dire il vero nemmeno avevo mai sentito nominare, probabilmente è molto poco pubblicizzata:
ecco l'intera istruzione:
$query="INSERT INTO #__kthumb VALUES('".$value."', '".$_FILES['image']['name']."')
ON DUPLICATE KEY UPDATE thumb = '".$_FILES['image']['name']."';";
Questo presuppone che esista una chiave definita, il che non è sempre vero. Ma a te penso vada benissimo così. :D
per quanto riguarda firebird, il problema è che, siccome sto sviluppando su joomla, non posso fare a meno di utilizzare MySQL ma grazie lo stesso per la gritta.
sto informando mi giusto adesso su questo firebird, noto che memorizza i dati in un file di testo, questo potrebbe essere interessante.
No, non memorizza i dati su file di testo. Genera un unico file binario con tutto dentro (a differenza di MySQL e altri engine).
john_revelator
07-11-2009, 19:05
tutto risolto.
ho utilizzato questa espressione che a dire il vero nemmeno avevo mai sentito nominare, probabilmente è molto poco pubblicizzata:
ecco l'intera istruzione:
$query="INSERT INTO #__kthumb VALUES('".$value."', '".$_FILES['image']['name']."')
ON DUPLICATE KEY UPDATE thumb = '".$_FILES['image']['name']."';";
per quanto riguarda firebird, il problema è che, siccome sto sviluppando su joomla, non posso fare a meno di utilizzare MySQL ma grazie lo stesso per la gritta.
sto informando mi giusto adesso su questo firebird, noto che memorizza i dati in un file di testo, questo potrebbe essere interessante.
In Mysql esiste la funzione replace() per fare ciò che chiedi.
http://dev.mysql.com/doc/refman/5.0/en/replace.html
L'operazione che chiedi si chiama Upsert (this into that table)
In Oracle e' realizzata con l'istruzione MERGE.
Per poter dire che un motore "la applica" occorre che l'istruzione possa agire sui SET, non sul singolo record.
UPDATE, DELETE ed INSERT agiscono su set di record, e anche l'istruzione che realizza la upsert dovrebbe farlo per poter essere applicata efficentemente.
Es:
MERGE INTO bonuses b
USING (
SELECT employee_id, salary, dept_no
FROM employee
WHERE dept_no =20) e
ON (b.employee_id = e.employee_id)
WHEN MATCHED THEN
UPDATE SET b.bonus = e.salary * 0.1
DELETE WHERE e.salary<=40000;
WHEN NOT MATCHED THEN
INSERT (b.employee_id, b.bonus)
VALUES (e.employee_id, e.salary * 0.05)
WHERE (e.salary > 40000);
Per ciasun record della USING il motore valuetera' se dovra' inserire oppure aggiornare nella tabella destinzione. (qui poi sotto-aggiorna o sotto-cancella a seconda di un'altra condizione di ciascun record sorgente, ma e' solo perche' l'esempio taglia-cucito e' cosi')
PS: Oracle e' sempre gratuito e liberamente distribuibile anche per applicazioni commerciali
se non ho capito ma le il REPLACE cancella la tupla con chiave duplicata e la sostituisce con quella specificata.
questo vuol dire che devo per forza assegnare un valore a tutti i campi altrimenti viene usato il valore di default oppure lasciato vuoto, perdendo così i vecchi dati gia presenti.
con la clausola ON DUPLICATE KEY dovrebbero essere mantenute le informazioni gia presenti per quei campi che non vengono nuovamente specificati, giusto?
per quanto riguarda le performances credo che REPLACE sia più lenta in quanto effettua 2 queryes alo posto di una sola.
non so se ho detto qualcosa di sbagliato, potete confermare smentire qulche cosa?:confused:
vBulletin® v3.6.4, Copyright ©2000-2025, Jelsoft Enterprises Ltd.