Si la tabla existe, suelte la tabla y luego créelo, si no existe simplemente créelo

151

Estoy perplejo, no sé cómo hacer esto.

Básicamente, solo quiero crear una tabla, pero si existe, debe descartarse y volver a crearse, no truncarse, pero si no existe, simplemente créelo.

¿Alguien podría ayudar?

Gracias george

Jorge
fuente
@Shomz, eso es lo que querían. Sin embargo, la existencia de esta pregunta y las 20 mil visitas a esta página demuestran que eso es tan fácil como convertir el inglés al griego.
Pacerier
2
@Pacerier No podría estar más de acuerdo: διαγραφή πίνακα, εφόσον υπάρχει.
Shomz
@Shomz, hay un error gramatical.
Pacerier

Respuestas:

298

Solo ponga DROP TABLE IF EXISTS `tablename`;antes de su CREATE TABLEdeclaración.

Esa declaración descarta la tabla si existe, pero no arrojará un error si no existe.

Pepita G
fuente
1
¡Gracias! ¡Esto también funciona para una lista de tablas o vistas! DROP TABLE IF EXISTS 'table1', 'table2';y DROP VIEW IF EXISTS 'view1', 'view2';PD: ¿Qué brujería usaste para tener `s en el código en línea?
Campbeln
2
@Campbeln Simplemente duplique los backticks antes y después del segmento de código. Los backticks individuales se muestran textualmente.
r3mainer
43

Solo usa DROP TABLE IF EXISTS:

DROP TABLE IF EXISTS `foo`;
CREATE TABLE `foo` ( ... );

Intente buscar primero en la documentación de MySQL si tiene algún otro problema.

r3mainer
fuente
8

Bueno ... eh. Durante años, nadie mencionó una cosa sutil.

A pesar de que DROP TABLE IF EXISTS `bla`; CREATE TABLE `bla` ( ... );parece razonable, lleva a una situación en la que la tabla anterior ya no existe y la nueva aún no se ha creado: algunos clientes pueden intentar acceder a la tabla de temas en este momento.

La mejor manera es crear una tabla nueva e intercambiarla por una antigua (se pierde el contenido de la tabla):

CREATE TABLE `bla__new` (id int); /* if not ok: terminate, report error */
RENAME TABLE `bla__new` to `bla`; /* if ok: terminate, report success */
RENAME TABLE `bla` to `bla__old`, `bla__new` to `bla`;
DROP TABLE IF EXISTS `bla__old`;
  • Debe verificar el resultado CREATE ...y no continuar en caso de error , porque el error significa que otro hilo no terminó el mismo script: ya sea porque se bloqueó en el medio o simplemente no terminó aún; es una buena idea inspeccionar las cosas por ti mismo.
  • Luego, primero debe verificar el resultado RENAME ...y no continuar en caso de éxito : toda la operación se ha completado con éxito; aún más, ejecutar el siguiente RENAME ...puede (y será) inseguro si otro hilo ya ha comenzado la misma secuencia (es mejor cubrir este caso que no cubrirlo, vea la nota de bloqueo a continuación).
  • El segundo RENAME ...reemplaza atómicamente la definición de la tabla; consulte el manual de MySQL para obtener más detalles.
  • Por fin, DROP ...simplemente limpia la vieja mesa, obviamente.

Ajustar todas las declaraciones con algo como esto SELECT GET_LOCK('__upgrade', -1); ... DO RELEASE_LOCK('__upgrade');permite invocar todas las declaraciones secuencialmente sin verificación de errores, pero no creo que sea una buena idea: la complejidad aumenta y las funciones de bloqueo en MySQL no son seguras para la replicación basada en declaraciones.

Si los datos de la tabla deben sobrevivir a la actualización de la definición de la tabla ... Para el caso general, es una historia mucho más compleja sobre la comparación de las definiciones de la tabla para descubrir diferencias y producir una ALTER ...declaración adecuada , que no siempre es posible automáticamente, por ejemplo, cuando se cambian los nombres de las columnas.

Nota al margen 1: puede manejar vistas utilizando el mismo enfoque, en este caso CREATE/DROP TABLEsimplemente se transforma en CREATE/DROP VIEWmientras RENAME TABLEpermanece sin cambios. De hecho, incluso puede convertir la tabla a la vista y viceversa.

CREATE VIEW `foo__new` as ...; /* if not ok: terminate, report error */
RENAME TABLE `foo__new` to `foo`; /* if ok: terminate, report success */
RENAME TABLE `foo` to `foo__old`, `foo__new` to `foo`;
DROP VIEW IF EXISTS `foo__old`;

Nota al margen 2: los usuarios de MariaDB deberían estar contentos con CREATE OR REPLACE TABLE/VIEWeso, que ya se preocupa por el problema del tema y sus puntos finos.

Alex Offshore
fuente
1

Necesitaba soltar una tabla y volver a crear con datos de una vista. Estaba creando una tabla desde una vista y esto es lo que hice:

DROP TABLE <table_name>;
CREATE TABLE <table_name> AS SELECT * FROM <view>;

Lo anterior funcionó para mí usando MySQL MariaDb.

sirskoy
fuente
soltar tabla nombre_tabla; crear tabla como select * desde la vista;
sirskoy 01 de
Si estás en MariaDB (MySQL carece de esto), entonces puedes simplementeCREATE OR REPLACE <table_name> AS SELECT * FROM <view>;
Alex Offshore