Pagina 1 di 2 1 2 ultimoultimo
Visualizzazione dei risultati da 1 a 10 su 12
  1. #1
    Utente di HTML.it L'avatar di lyllo
    Registrato dal
    Apr 2001
    Messaggi
    832

    Inserimento record condizionale "IF NOT EXISTS"

    ciao a tutti,

    vorrei ridurre il numero di query ottimizzando così l'accesso al database.

    ho una tabella relazionale del tipo id_oggetto=id_altro_oggetto, per cui senza chiavi primarie o indici.

    il punto che sorge è in fase di AGGIORNAMENTO di un campo.
    tale campo contiene infatti una serie di informazioni che poi vengono splittate e inserite in un database, alcune delle quali possono essere già presenti, alcune NUOVE.

    vorrei una cosa tipo

    INSERT INTO tbl_relazioni (id, id_oggetto) IF NOT EXISTS (coppia di valori)

    si può fare, oppure sono costretto a fare, per ogni coppia di valori un SELECT e SE num_rows <=0 ALLORA INSERT?
    (così mi obbliga a fare una query di selezione per ogni valore nel campo! )

    grazie e

  2. #2
    fa' un esempio (e mmmmmmmm vuoi dire che db usi, come da regolamento?)

  3. #3
    Utente di HTML.it L'avatar di nicola75ss
    Registrato dal
    Nov 2004
    Messaggi
    12,922
    Credo che l'inserimento di un indice univoco sia comunque necessario.

    codice:
     drop table if exists lyllo;
     create table lyllo (
     id_oggetto int unsigned not null,
     id_altro_oggetto int unsigned not null,
     unique (id_oggetto,id_altro_oggetto)
     ) engine = myisam;
     
    replace into lyllo values 
    (1,2),
    (2,5),
    (2,5),
    (1,3),
    (1,2);
    Oppure

    codice:
    truncate lyllo;
    
    insert ignore into lyllo values 
    (1,2),
    (2,5),
    (2,5),
    (1,3),
    (1,2);
    edit. Come ti ha scritto optime va sempre indicato il db.
    Io ho dato per scontato che sia mysql visti i trascorsi forumistici.

  4. #4
    Utente di HTML.it L'avatar di lyllo
    Registrato dal
    Apr 2001
    Messaggi
    832
    Originariamente inviato da nicola75ss
    Credo che l'inserimento di un indice univoco sia comunque necessario.

    codice:
     drop table if exists lyllo;
     create table lyllo (
     id_oggetto int unsigned not null,
     id_altro_oggetto int unsigned not null,
     unique (id_oggetto,id_altro_oggetto)
     ) engine = myisam;
     
    replace into lyllo values 
    (1,2),
    (2,5),
    (2,5),
    (1,3),
    (1,2);
    Oppure

    codice:
    truncate lyllo;
    
    insert ignore into lyllo values 
    (1,2),
    (2,5),
    (2,5),
    (1,3),
    (1,2);
    edit. Come ti ha scritto optime va sempre indicato il db.
    Io ho dato per scontato che sia mysql visti i trascorsi forumistici.
    hai visto che però sono venuto subito da te?
    ma se metto una chiave univoca poi non mi da errore di doppi inserimenti?
    unique (id_oggetto,id_altro_oggetto) significa che SIA uno che laltro sono UNIVOCI, NON la coppia..
    quindi se io vado a mettere un record con un id che è già inserito non genera un errore?


  5. #5
    Utente di HTML.it L'avatar di nicola75ss
    Registrato dal
    Nov 2004
    Messaggi
    12,922
    Originariamente inviato da lyllo
    hai visto che però sono venuto subito da te?
    ma se metto una chiave univoca poi non mi da errore di doppi inserimenti?
    unique (id_oggetto,id_altro_oggetto) significa che SIA uno che laltro sono UNIVOCI, NON la coppia..
    quindi se io vado a mettere un record con un id che è già inserito non genera un errore?

    L'unicità è riferita alla coppia. Prova il dump e le due opzioni che ti ho scritto.
    La parola chiave ignore nella insert evita che la query venga interrotta a causa della violazione del vincolo imposto e prosegue con gli inserimenti validi.

  6. #6
    Uso questo thread per non duplicare le discussioni.
    In pratica ho lo stesso problema ma in più vorrei ottenere gli id delle righe.

    In pratica ho delle tabelle MySQL che si referenziano l'un l'altra e vorrei ottenere qualcosa del tipo:
    codice:
    SELECT id FROM users WHERE email = $email
    
    if( num_rows > 0 ) {
           return $row[id]
    } else {
           INSERT INTO users ($email)
           return last_insert_id
    }
    Esiste la possibilità di fare tutto questo via MySQL con un'unica query?
    Da un lato mi piacerebbe capirlo per semplice curiosità perchè posso ovviare anche con il codice che ho usato per l'esempio; dall'altro credo che sarebbe comunque utile perchè gli inserimenti sono tanti e, tralasciando gli if, su n inserimenti sono almeno n query e la cosa potrebbe diventare pesante da elaborare.

    Grazie
    eCommerceRS.NET - Commerciante, vendi on-line!
    Il mio nick è mircov e non mirco!!!

  7. #7
    beh, scusa la domanda ma perché hai bisogno dell'id utente o dell'inserimento dell'utente tramite esclusivamente la e-mail?

    generalmente per evitare la tripletta SELECT/INSERT|UPDATE uso una INSERT ... ON DUPLICATE KEYS UPDATE ma non credo che nel tuo caso ci sia altra soluzione
    The fastest Redis alternative ... cachegrand! https://github.com/danielealbano/cachegrand

  8. #8
    Devo usare per forza l'email perchè i dati arrivano da sorgenti esterne (per esempio un csv).
    Quindi nella mia tabella potrei avere già memorizzati alcuni utenti.

    Facendo il matching sull'email controllo se quel particolare utente è già presente nel mio database. Se lo è vedo quale id ha e uso quello per costruire le altre referenze interne per le altre info che devo memorizzare.

    Se invece non ce l'ho, prima lo creo e poi uso il nuovo id per procedere.

    ON DUPLICATE KEYS UPDATE potrebbe andare bene, ma comunque nel caso in cui esegua l'UPDATE poi non potrei ottenere l'id se non con una seconda query che selezioni l'id.

    In totale sono sempre due query mentre io ne voglio una in ogni caso, sia che inserisca sia che aggiorni.

    Dico questo senza aver provato il costrutto ma solo leggendo quello che sta scritto qui

    http://dev.mysql.com/doc/refman/5.0/...duplicate.html

    With ON DUPLICATE KEY UPDATE, the affected-rows value per row is 1 if the row is inserted as a new row and 2 if an existing row is updated.

    [...]

    If a table contains an AUTO_INCREMENT column and INSERT ... UPDATE inserts a row, the LAST_INSERT_ID() function returns the AUTO_INCREMENT value. If the statement updates a row instead, LAST_INSERT_ID() is not meaningful. However, you can work around this by using LAST_INSERT_ID(expr). Suppose that id is the AUTO_INCREMENT column. To make LAST_INSERT_ID() meaningful for updates, insert rows as follows:

    codice:
    INSERT INTO table (a,b,c) VALUES (1,2,3)
      ON DUPLICATE KEY UPDATE id=LAST_INSERT_ID(id), c=3;
    The DELAYED option is ignored when you use ON DUPLICATE KEY UPDATE.
    Suggerisce un modo per usare l'id anche nel caso di UPDATE ma 1) non credo di aver capito cosa intenda e 2) non mi pare in ogni caso mi restituisca l'id della riga coinvolta nell'UPDATE.

    Mi sbaglio, mi sfugge qualcosa? Oppure l'esempio fa al caso mio e io semplicemente non l'ho capito?
    eCommerceRS.NET - Commerciante, vendi on-line!
    Il mio nick è mircov e non mirco!!!

  9. #9
    per quello che devi fare tu ti servono sempre e comunque 2 query, tranne che usi l'email come chiave primaria, in quel caso puoi farne 1 soltanto

    non credo ci siano molti altri modi
    The fastest Redis alternative ... cachegrand! https://github.com/danielealbano/cachegrand

  10. #10
    Originariamente inviato da daniele_dll
    per quello che devi fare tu ti servono sempre e comunque 2 query, tranne che usi l'email come chiave primaria, in quel caso puoi farne 1 soltanto

    non credo ci siano molti altri modi
    E già, l'avevo immaginato.
    Però gli utenti vengono gestiti da un CMS e la tabella è del CMS, quindi dovrei andare a modificare la struttura di quella tabella e tenere traccia dell'eccezione che ho creato per i futuri aggiornamenti.

    Quindi a questo punto non mi rimane che lasciare le cose così, con due query, e ragionarci meglio quando arriverò alla fase dell'ottimizzazione dello script.

    Grazie mille per gli spunti daniele_dll,
    ciao
    eCommerceRS.NET - Commerciante, vendi on-line!
    Il mio nick è mircov e non mirco!!!

Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2025 vBulletin Solutions, Inc. All rights reserved.