Sintaxis de ALTER TABLE con dbDelta

8 ene 2013, 10:58:33
Vistas: 15.7K
Votos: 5

Debido a algunos cambios en la base de datos, necesito alterar una tabla para añadir una columna, pero aunque la función se ejecuta, la tabla no se modifica. Aquí está el código ALTER TABLE que he escrito:

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

No pude encontrar la sintaxis para ALTER TABLE con dbDelta en ninguna parte en línea. EDIT: Después de revisar la sentencia ALTER TABLE en el plugin de Gravity Forms, actualicé la declaración en una sola línea.

2
Comentarios

La sintaxis es la misma que la sintaxis general de MySQL, por lo que esta pregunta no es específica de WordPress. Busca en Google la sintaxis correcta para un comando ALTER TABLE

shea shea
8 ene 2013 11:11:45

La consulta de MySQL es correcta. El problema está en el lado de dbDelta. Por lo tanto, es una consulta de WordPress. Probé el comando en la consola de MySQL por mí mismo antes de publicarlo aquí.

mehulved mehulved
8 ene 2013 11:33:31
Todas las respuestas a la pregunta 2
11
17

Has usado incorrectamente la función dbDelta.

El propósito principal de esta función es pasarle un comando SQL de creación de tablas.

Si la tabla no existe, la crea.

Si la tabla existe pero no coincide, se modifica hasta que coincida. Esto incluye agregar y actualizar columnas, índices y otros aspectos.

Por lo tanto, lo que debes hacer es ejecutar dbDelta y proporcionarle tu SQL de creación de tabla, no SQL de alteración de tabla.

Consulta aquí la documentación del Codex sobre cómo agregar una actualización/alteración a una tabla usando dbDelta

¡Pero hay más! dbDelta es una función exigente, no puedes poner cualquier sentencia SQL allí, debe estar formateada apropiadamente

Esto es lo que dice el Codex en la misma página:

  1. Debes poner cada campo en su propia línea en tu sentencia SQL.
  2. Debes tener dos espacios entre las palabras PRIMARY KEY y la definición de tu clave primaria.
  3. Debes usar la palabra clave KEY en lugar de su sinónimo INDEX y debes incluir al menos una KEY.
  4. No debes usar apóstrofes o backticks alrededor de los nombres de los campos.

Y de otra fuente:

Función dbDelta

Como mencioné antes en uno de mis artículos, la función dbDelta tiene la capacidad de examinar la estructura actual de la tabla, compararla con la estructura deseada y agregar o modificar la tabla según sea necesario, por lo que puede ser muy útil para actualizaciones de nuestro plugin. Sin embargo, a diferencia de muchas funciones de WordPress, dbDelta es la más exigente y problemática. Para que la función dbDelta funcione, se deben cumplir algunos criterios.

  1. Tienes que poner cada campo en su propia línea en tu sentencia SQL.
  2. Tienes que tener dos espacios entre las palabras PRIMARY KEY y la definición de tu clave primaria.
  3. Debes usar la palabra clave KEY en lugar de su sinónimo INDEX y debes incluir al menos una KEY.

Bueno, los criterios anteriores parecen fáciles de lograr. Pero espera a que te golpeen.

8 ene 2013 11:23:48
Comentarios

dbDelta() admite agregar y actualizar columnas. Ver: http://wordpress.stackexchange.com/q/76926/19726

shea shea
8 ene 2013 11:37:19

Nunca dije que no lo hiciera, solo dije que la forma en que lo hizo era incorrecta. Usa una declaración CREATE para la tabla que deseas, no una declaración ALTER, y dbDelta creará las columnas por ti y modificará la tabla hasta que coincida con lo que dice el SQL

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

De acuerdo, lo entiendo. ¡Nunca me di cuenta de que se podía hacer esto con dbDelta()! +1

shea shea
8 ene 2013 11:47:38

Entonces, actualicé la sentencia SQL para agregar la columna de precio pero obtuve un error de BD indicando que la tabla ya existe. Aquí está el mensaje de error Error de base de datos de WordPress: [La tabla 'wp_booking_packages' ya existe] 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) ) y verifiqué en la consola de MySQL que la columna aún no existe.

mehulved mehulved
8 ene 2013 11:53:03

He actualizado mi respuesta con más detalles. Si puedes publicar cualquier código futuro usando un gist para que pueda verlo en su totalidad? Los comentarios tienden a arruinar el formato y los saltos de línea, lo que podría marcar la diferencia entre que funcione o no dbDelta aquí

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

http://gist.github.com por si no lo conoces

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

Aquí hay un gist https://gist.github.com/4482802

mehulved mehulved
8 ene 2013 12:39:27

@TomJNowell ¿Qué pasa si tengo un campo en mi sentencia CREATE TABLE con tipo de dato text, y ahora quiero cambiar el tipo de dato de ese campo a bigint, en este caso dbDelta falla. ¿Hay alguna forma de hacerlo?

IAmDhar IAmDhar
6 abr 2017 21:49:08

@IAmDhar ¿cómo convertiría la palabra "banana" en un número? Haría esa pregunta como una pregunta completamente nueva, es poco probable que alguien tenga la respuesta, y hay una buena probabilidad de que esté más allá de las capacidades de dbDelta (dbDelta cambiará la columna, no cambiará los datos en sí)

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

@mehulved el problema aquí podría ser tan simple como que no hay un espacio entre el nombre de la tabla y el paréntesis de apertura. dbDelta es extremadamente sensible a estas cosas, asegúrate de que la sentencia SQL esté bien formateada y limpia, incluso si en SQL estándar normalmente no se requiere un espacio, agrégalo de todos modos

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

Gracias por señalar que debe haber un espacio entre el nombre de la tabla y el paréntesis de apertura. ¡Esta información acaba de resolver mi problema con la actualización de tablas!

sebastian sebastian
5 may 2019 19:13:19
Mostrar los 6 comentarios restantes
1

Para agregar una columna a alguna tabla de WordPress en la base de datos, puedes usar $wpdb para ello:

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() devuelve false si tu consulta falló, según la documentación del método. Así que podrías escribir una declaración if-else para hacer algo en caso de éxito o error:

if ( $query_result === false ){
    // ocurrió un error
} else {
    // éxito
}

Si necesitas agregar tu nueva columna después de una columna específica, simplemente usa AFTER en la consulta:

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

También podrías modificar

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

o eliminar una columna

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

Un pequeño tip: En PHP, dentro de comillas dobles ("), puedes usar variables entre llaves ("foo {$var} bar") o sin ellas ("foo $var bar") para insertar variables en cadenas, en lugar de concatenación ("foo " . $var . " bar"). Lo uso en el código anterior. Aprende más sobre el análisis de cadenas en php.

11 ene 2021 18:04:04
Comentarios

quizás la respuesta de Tom sea más adecuada para el tema, esta respuesta sigue siendo útil para algunos escenarios. ¡gracias!

Dreanmer Dreanmer
31 jul 2022 18:23:27