Qualcosa mi ha infastidito su questa domanda ... perché hai bisogno dell'inserzione_id di ogni riga? Mi sembra che se si sta inserendo nella tabella delle impostazioni per correlare le impostazioni all'utente, sarebbe meglio aggiungere una sorta di chiave utente alla tabella. Sto probabilmente solo non vedere l'intera immagine, ma questa è l'idea che sto ricevendo:
+---------------------------------------+
| `settings` |
+------+--------+-----------+-----------+
| id | user | setting | value |
+------+--------+-----------+-----------+
| `id` INT(11) PRIMARY AUTO_INCREMENT |
+---------------------------------------+
| `user` INT(11) |
+---------------------------------------+
| `setting` VARCHAR(15) |
+---------------------------------------+
| `value` VARCHAR(25) |
+---------------------------------------+
+---------------------------------------+
| `users` |
+------+--------+--------+--------------+
| id | name | email | etc |
+------+--------+--------+--------------+
| `id` INT(11) PRIMARY AUTO_INCREMENT |
+---------------------------------------+
| `name` VARCHAR(32) |
+---------------------------------------+
| `email` VARCHAR(64) |
+---------------------------------------+
| `etc` VARCHAR(64) |
+---------------------------------------+
Il mio pensiero di base è che ciò che si sta facendo con l'insert_id (s) è quindi in qualche modo cercando per creare un riferimento tra gli utenti e le impostazioni in modo da sapere chi imposta cosa e restituirgli le impostazioni in un secondo momento.
Se ho completamente perso il punto, per favore, mi guida indietro sul soggetto e cercherò di trovare un'altra soluzione, ma se sto colpendo ovunque vicino a dove si sta tentando di andare:
Se si sta tentando di correlare le due tabelle utilizzando insert_id (s), non sarebbe più opportuno qualcosa di simile al codice seguente (presupponendo che si abbia una struttura tabella simile a quella precedente):
I'll supponiamo che $ user sia un riferimento a un particolare utente (users
. id
).
Suppongo anche che tu abbia un array associativo chiamato $ settings che stai cercando di inserire nel database.
$mysqli = new mysqli('host', 'username', 'password', 'database') or trigger_error('[MYSQLI]: Could not connect.');
if ($mysqli)
{
foreach ($settings AS $setting_name=>$setting_value)
{
// I'll do individual queries here so error checking between is easy, but you could join them into a single query string and use a $mysqli->multi_query();
// I'll give two examples of how to make the multi_query string below.
$sql = "INSERT INTO `settings` (`id`, `user`, `setting`, `value`) VALUES ('', $user, '$setting_name', '$setting_value')";
$mysqli->query($sql) or trigger_error('[MYSQLI]: ' . $mysqli->error . '['.$sql.']';
}
$mysqli->close() // Since we know in this scope that $mysqli was created we need to close it when we are finished with it.
}
Ora, quando hai bisogno di impostazioni dell'utente si potrebbe fare una SELECT con un JOIN di mettere tutte le impostazioni e le informazioni utente insieme e mi perdoni se mi pidocchio questo po 'su, perché io sono di gran lunga non un mysql (i) esperto, quindi non sono sicuro che dovrai fare qualcosa di speciale in quanto ci sono più voci nella tabella delle impostazioni e una singola voce nella tabella degli utenti, ma sono sicuro che qualcuno può impostarci entrambi se io rovinare tutto:
$mysqli = new mysqli('host', 'username', 'password', 'database') or trigger_error('[MYSQLI]: Unable to connect.');
if ($mysqli)
{
$sql = "SELECT `users`.`name`, `users`.`email`, `users`.`id`, `users`.`etc`, `settings`.`setting`, `settings`.`value` FROM `settings` JOIN (`users`) ON (`users`.`id`=`settings`.`user`) WHERE `settings`.`user`=$user GROUP BY `settings`.`user` ORDER BY `settings`.`user` ASC";
if ($result=$mysqli->query($sql))
{
if ($result->num_rows == 0)
echo "Uh oh! $user has no settings or doesn't exist!";
else
{
// Not sure if my sql would get multiple results or if it would get it all in one row like I want so I'll assume multiple which will work either way.
while ($row=$result->fetch_array())
print_r($row); // Just print the array of settings to see that it worked.
}
$result->free(); // We are done with our results so we release it back into the wild.
} else trigger_error('[MYSQLI]: '.$mysqli->error . '['.$sql.']');
$mysqli->close(); // Our if ($mysqli) tells us that in this scope $mysqli exists, so we need to close it since we are finished.
}
Come ho già detto, io sono di gran lunga non un mysql (i) esperto e probabilmente ci sono modi per ottimizzare le cose e forse ho fatto alcuni errori con la Synta x sulla mia dichiarazione JOIN o semplicemente usato clausole superflue come il GRUPPO BY. Ho fatto il SELECT un pull da settings
e mi sono unito a users
perché non ero sicuro che unire le impostazioni agli utenti avrebbe prodotto un singolo risultato contenente utenti e tutti i valori possibili dalle impostazioni che corrispondevano alla nostra clausola WHERE. Mi sono mai unito a A
con B
dove c'era 1 risultato in ciascuno, ma sono fiducioso che un JOIN è nella giusta area generale.
alternativa alle molteplici domande, ho detto che avrei dare esempi di costruzione di una singola stringa di query per un multi_query, quindi:
$arr = array();
foreach($settings AS $setting_name=>$setting_value)
{
$arr[] = "INSERT INTO `settings` (`id`, `user`, `setting`, `value`) VALUES ('', $user, '$setting_name', '$setting_value')";
}
$sql = join('; ', $arr);
o
foreach($settings AS $setting_name=>$setting_value)
{
$sql = (isset($sql)) ? $sql.'; '."INSERT INTO `settings` (`id`, `user`, `setting`, `value`) VALUES ('', $user, '$setting_name', '$setting_value')" : "INSERT INTO `settings` (`id`, `user`, `setting`, `value`) VALUES ('', $user, '$setting_name', '$setting_value')";
}
Un'ultima cosa voglio sottolineare : A meno che tu non stia specificatamente richiedendo più voci della stessa impostazione per l'utente, allora potresti fare un UPDATE prima della tua query INSERT e fare solo l'INSERT se il risultante $ mysqli-> insert_id == 0. Se stai tentando di mantenere un cronologia delle modifiche alle impostazioni per gli utenti ed è per questo avete bisogno di più voci poi vorrei suggerire la creazione di un tavolo separato con un log che contiene una struttura di tabella del tipo:
+--------------------------------------------------+
| `logs` |
+------+--------+--------+-----------+-------------+
| id | time | user | setting | new_value |
+------+--------+--------+-----------+-------------+
| `id` INT(11) PRIMARY AUTO_INCREMENT |
+--------------------------------------------------+
| `time` TIMESTAMP |
+--------------------------------------------------+
| `user` INT(11) |
+--------------------------------------------------+
| `setting` INT(11) |
+--------------------------------------------------+
| `new_value` VARCHAR(25) |
+--------------------------------------------------+
Se si effettua il default del time
del CURRENT_TIMESTAMP o semplicemente inserire la data ('Ymd G: i: s') in quel campo, quindi è possibile tenere traccia delle modifiche alle impostazioni inserendo nel registro quando vengono create o modificate nuove impostazioni.
Per eseguire gli INSERTI se l'AGGIORNAMENTO non ha modificato nulla, è possibile utilizzare due istruzioni separate. È anche possibile farlo con "INSERT VALUES() ON DUPLICATE KEY UPDATE ...", ma questo metodo non è apparentemente raccomandato su tabelle con più campi UNIQUE. Utilizzare il secondo metodo significherebbe una singola query, ma dovresti fare la combinazione di user
e setting
UNICA (o forse DISTINCT?). Se hai fatto setting
UNICO allora saresti in grado di avere uno solo setting
= 'pippo' nella tabella a meno che non mi sbagli. Per farlo con due affermazioni si dovrebbe fare qualcosa di simile:
$sql = "UPDATE `settings` SET `value`='bar' WHERE `user`=$user AND `setting`='foo' LIMIT 1";
$mysqli->query() or trigger_error('[MYSQLI]: ' . $mysqli->error . '['.$sql.']');
if ($mysqli->affected_rows == 0)
{
$sql = "INSERT INTO `settings` (`id`, `user`, `setting`, `value`) VALUES ('', $user, 'foo', 'bar')";
$mysqli->query($sql) or trigger_error('[MYSQLI]: ' . $mysqli->error . '['.$sql.']');
}
Nel codice di cui sopra si potrebbe sostituire $ mysqli-> insert_id a $ mysqli-> affected_rows se preferite, ma il risultato finale è lo stesso. L'istruzione INSERT viene chiamata solo se l'UPDATE non ha modificato nulla nella tabella (il che indicherebbe che non c'erano record per quell'impostazione e quell'utente).
Mi scuso che questa è una risposta molto lunga e si è allontanata dalla tua domanda iniziale, ma spero che sia relavent al tuo vero scopo/obiettivo. Attendo con ansia la vostra risposta e i commenti sui modi per migliorare le mie istruzioni SQL dai veri master SQL.
Non sono nemmeno sicuro del punto 2.Se fossi in me, direi di creare una tabella temporanea, aggiungendo ogni last_insert_id ad essa, e poi restituirla. O meglio ancora, avere un altro modo di selezionare ciò che era appena successo, (utente e dire un timestamp datalastchanged) –
Risposta semplice no. Non è robusto e mentre qualsiasi individuo last_insert_id() può essere dipendente dalla connessione, non fornisce una * garanzia * che tutti gli inserti saranno in un blocco simultaneo e non interlacciati con inserimenti da un altro processo concorrente. Nella programmazione è molto meglio affidarsi a una solida ingegneria piuttosto che alla sensazione che dovrebbe essere ok. – Anigel
Sarei d'accordo con le questioni precedenti. Tuttavia potrebbe essere possibile avere un campo extra sulla tabella che stai inserendo e inserire un identificativo univoco. Quindi puoi leggere quella tabella per tutti i record con quell'identificatore univoco per ottenere l'elenco degli ID inseriti. Sarei ancora preoccupato di quale ID si riferisse a quale serie di dati inseriti non fosse definito. – Kickstart