Sintassi dbDelta ALTER TABLE?

8 gen 2013, 10:58:33
Visualizzazioni: 15.7K
Voti: 5

A causa di alcune modifiche al database, devo alterare una tabella per aggiungere una colonna, ma nonostante la funzione venga eseguita, la tabella non viene modificata. Ecco il codice ALTER TABLE che ho scritto:

$sql = "ALTER TABLE " . $packagetable . " ADD COLUMN price decimal(14,2) NOT NULL AFTER description;";
dbDelta($sql);

Non sono riuscito a trovare da nessuna parte online la sintassi corretta per ALTER TABLE con dbDelta. MODIFICA: Dopo aver esaminato l'istruzione ALTER TABLE nel plugin Gravity Forms, ho aggiornato l'istruzione in una singola riga.

2
Commenti

La sintassi è la stessa della sintassi generale di MySQL, quindi questa domanda non è specifica per WordPress. Cerca su Google la sintassi corretta per un comando ALTER TABLE

shea shea
8 gen 2013 11:11:45

La query MySQL è corretta. Il problema è sul lato di dbDelta. Quindi, si tratta di una query di WordPress. Ho provato il comando nella console MySQL personalmente prima di pubblicarlo qui.

mehulved mehulved
8 gen 2013 11:33:31
Tutte le risposte alla domanda 2
11
17

Hai utilizzato la funzione dbDelta in modo errato.

Lo scopo principale di questa funzione è che le passi un comando SQL per la creazione di una tabella.

Se la tabella non esiste, la crea.

Se la tabella esiste ma non corrisponde, viene modificata fino a farla corrispondere. Questo include l'aggiunta e l'aggiornamento di colonne, indici e altri aspetti.

Quindi quello che devi fare è eseguire dbDelta e fornirgli il tuo SQL di creazione della tabella, non di modifica della tabella.

Vedi qui per la spiegazione del Codex su come aggiungere un aggiornamento/modifica a una tabella utilizzando dbDelta

Ma c'è di più! dbDelta è una funzione esigente, non puoi semplicemente metterci qualsiasi istruzione SQL, deve essere formattata correttamente.

Ecco cosa dice il Codex nella stessa pagina:

  1. Devi mettere ogni campo nella sua riga nell'istruzione SQL.
  2. Devi avere due spazi tra le parole PRIMARY KEY e la definizione della tua chiave primaria.
  3. Devi usare la parola chiave KEY invece del suo sinonimo INDEX e devi includere almeno un KEY.
  4. Non devi usare apostrofi o backtick intorno ai nomi dei campi.

E da un'altra fonte:

Funzione dbDelta

Come ho menzionato prima in uno dei miei articoli, la funzione dbDelta ha la capacità di esaminare la struttura attuale della tabella, confrontarla con la struttura desiderata e aggiungere o modificare la tabella secondo necessità, quindi può essere molto utile per gli aggiornamenti del nostro plugin. Tuttavia, a differenza di molte funzioni di WordPress, dbDelta è la più esigente e problematica. Affinché la funzione dbDelta funzioni, devono essere soddisfatti alcuni criteri.

  1. Devi mettere ogni campo nella sua riga nell'istruzione SQL.
  2. Devi avere due spazi tra le parole PRIMARY KEY e la definizione della tua chiave primaria.
  3. Devi usare la parola chiave KEY invece del suo sinonimo INDEX e devi includere almeno un KEY.

Bene, i criteri sopra sembrano facili da raggiungere. Ma aspetta che ti colpiscano.

8 gen 2013 11:23:48
Commenti

dbDelta() supporta l'aggiunta e l'aggiornamento di colonne. Vedi: http://wordpress.stackexchange.com/q/76926/19726

shea shea
8 gen 2013 11:37:19

Non ho mai detto che non lo faccia, ho solo detto che il modo in cui l'ha fatto era sbagliato. Usa un'istruzione CREATE per la tabella che vuoi, non un'istruzione ALTER, e dbDelta creerà le colonne per te e modificherà la tabella finché non corrisponderà a ciò che dice l'SQL

Tom J Nowell Tom J Nowell
8 gen 2013 11:45:15

Ok, ho capito. Non avevo mai realizzato che si potesse fare questo con dbDelta()! +1

shea shea
8 gen 2013 11:47:38

Quindi, ho aggiornato l'istruzione SQL per aggiungere la colonna del prezzo ma ho ricevuto un errore del database che dice che la tabella esiste già. Ecco il messaggio di errore Errore del database WordPress: [La tabella 'wp_booking_packages' esiste già] CREATE TABLE wp_booking_packages( id mediumint(9) NOT NULL AUTO_INCREMENT, name text NOT NULL, description text NOT NULL, price decimal(14,2) NOT NULL, city1 text NOT NULL, city2 text NOT NULL, PRIMARY KEY (id) ) e ho verificato nella console MySQL che la colonna ancora non esiste.

mehulved mehulved
8 gen 2013 11:53:03

Ho aggiornato la mia risposta con maggiori dettagli. Se puoi postare qualsiasi codice futuro utilizzando un gist così posso vederlo nella sua interezza? I commenti tendono a rovinare la formattazione e le nuove righe, che potrebbero fare la differenza tra un codice che funziona e uno che non funziona dbDelta in questo caso

Tom J Nowell Tom J Nowell
8 gen 2013 12:32:45

http://gist.github.com se non lo conosci già

Tom J Nowell Tom J Nowell
8 gen 2013 12:36:24

Ecco una gist https://gist.github.com/4482802

mehulved mehulved
8 gen 2013 12:39:27

@TomJNowell Cosa succederebbe se avessi un campo nella mia istruzione CREATE TABLE con tipo di dati TEXT, e ora volessi cambiare il tipo di dati di quel campo in BIGINT? In questo caso dbDelta fallisce. Esiste un modo per farlo?

IAmDhar IAmDhar
6 apr 2017 21:49:08

@IAmDhar Come potrei convertire la parola "banana" in un numero? Farei questa domanda come una nuova domanda a parte, è improbabile che qualcuno abbia la risposta, e c'è una buona probabilità che sia oltre le capacità di dbDelta (dbDelta cambierà la colonna, ma non i dati stessi)

Tom J Nowell Tom J Nowell
6 apr 2017 22:52:35

@mehulved il problema qui potrebbe essere semplice come la mancanza di uno spazio tra il nome della tabella e la parentesi aperta. dbDelta è estremamente sensibile a queste cose, assicurati che l'istruzione SQL sia ben formattata e pulita, anche se in SQL standard uno spazio normalmente non è richiesto ecc., aggiungilo comunque

Tom J Nowell Tom J Nowell
6 apr 2017 22:54:26

Grazie per aver sottolineato che ci deve essere uno spazio tra il nome della tabella e la parentesi aperta. Questa informazione ha appena risolto il mio problema con l'aggiornamento delle tabelle!

sebastian sebastian
5 mag 2019 19:13:19
Mostra i restanti 6 commenti
1

Per aggiungere una colonna a una tabella di WordPress nel database, puoi utilizzare $wpdb:

global $wpdb;

$table = $wpdb->prefix . 'my_table';
$sql = "ALTER TABLE `{$table}`
        ADD `new_column` VARCHAR(20) NULL DEFAULT NULL;";

$query_result = $wpdb->query( $sql );

$wpdb->query() restituisce false se la query ha generato un errore, secondo la documentazione del metodo. Quindi puoi scrivere un'istruzione if-else per gestire successo o errore:

if ( $query_result === false ){
    // si è verificato un errore
} else {
    // successo
}

Se devi aggiungere la nuova colonna dopo una colonna specifica, usa AFTER nella query:

$sql = "ALTER TABLE `{$table}`
        ADD `new_column` VARCHAR(20) NULL DEFAULT NULL
        AFTER `exist_column`;";

Inoltre, puoi modificare

$sql = "ALTER TABLE `{$table}`
        MODIFY COLUMN `exist_column` VARCHAR(20) NULL DEFAULT NULL;";

o eliminare una colonna

$sql = "ALTER TABLE `{$table}`
        MODIFY COLUMN `exist_column`;";

Piccolo consiglio: In PHP, all'interno delle virgolette doppie ("), puoi usare variabili tra parentesi graffe ("foo {$var} bar") o senza ("foo $var bar") per inserire variabili in una stringa, invece della concatenazione ("foo " . $var . " bar"). L'ho usato nel codice sopra. Scopri di più sul parsing delle stringhe in php.

11 gen 2021 18:04:04
Commenti

forse la risposta di Tom è più adatta all'argomento, questa risposta è comunque utile per alcuni scenari. grazie!

Dreanmer Dreanmer
31 lug 2022 18:23:27