2009-10-23 12 views
6

Busco a una única secuencia de comandos de MySQL para convertir todos los nombres de columna en una base de datos en minúsculas de una sola vez ...una secuencia de comandos de MySQL para convertir los nombres de columna a minúsculas

He heredado una base de datos MySQL que tiene una muchos nombres de columnas de casos mixtos (150 tablas con una extraña convención de nomenclatura) y no quiero pasar manualmente cada tabla por tabla para hacer esto.

¿Alguien ha recibido un script así?

Gracias

Respuesta

2

Puede resolver esta tarea mediante la construcción de una secuencia de comandos, a partir de la salida de esta declaración:

SELECT table_name, column_name, data_type 
FROM information_schema.columns 
WHERE table_schema = 'dbname'; 
ORDER BY table_name 

detalles acerca de esta función se pueden encontrar aquí "MYSQL::The INFORMATION_SCHEMA COLUMNS Table"

Entonces puede usar la función ALTER TABLE .. CHANGE para cambiar el nombre de las columnas

por ej.

ALTER TABLE mytable CHANGE old_name new_name varchar(5); 

Véase también "MYSQL::ALTER TABLE Syntax"

tipo de datos diferentes tienen diferentes requisitos por lo que necesita de los sindicatos:

SELECT 'ALTER TABLE '||table_name||' CHANGE '|| column_name||' '||lower(column_name)||' '||datatype||'('||CHAR(character_maximum_length)||');' AS Line 
    FROM information_schema.columns 
    WHERE table_schema = dbname and datatype in ('CHAR', 'VARCHAR') 
    ORDER BY table_name 
    UNION 
SELECT 'ALTER TABLE '||table_name||' CHANGE '|| column_name||' '||lower(column_name)||' '||datatype||'('||CHAR(numeric_precision)||');' AS Line 
    FROM information_schema.columns 
    WHERE table_schema = dbname and datatype in ('INTEGER') 
    ORDER BY table_name 
    UNION 
SELECT 'ALTER TABLE '||table_name||' CHANGE '|| column_name||' '||lower(column_name)||' '||datatype||'('||CHAR(numeric_precision)||','||CHAR(numeric_scale)|');' AS Line 
    FROM information_schema.columns 
    WHERE table_schema = dbname and datatype in ('FLOAT') 
    ORDER BY table_name 
    UNION 
SELECT 'ALTER TABLE '||table_name||' CHANGE '|| column_name||' '||lower(column_name)||' '||datatype||');' AS Line 
    FROM information_schema.columns 
    WHERE table_schema = dbname and datatype in ('DATE') 
    ORDER BY table_name 
+0

Gracias, esto me acercó lo suficiente .... – Rippo

+0

No pude probarlo, pero estoy contento de haber estado cerca :) – Adrian

+0

Recibiremos este error "ERROR 1054 (42S22): Columna desconocida 'tipo de datos' en 'lista de campo' "en mysql 5.7. Use 'data_type', pero no 'datatype' – user3081809

6

En caso de que alguien más quiere este continuación se muestra un ejemplo de la consulta se ha completado, por favor prueba antes de usar .....

EDITAR SOLUCIÓN COMPLETADA COMO SE SOLICITA

SELECT CONCAT(
'ALTER TABLE ', table_name, 
' CHANGE ', column_name, ' ', 
LOWER(column_name), ' ', column_type, ' ', extra, 
CASE WHEN IS_NULLABLE = 'YES' THEN ' NULL' ELSE ' NOT NULL' END, ';') AS line 
FROM information_schema.columns 
WHERE table_schema = '<DBNAME>' 
AND data_type IN ('char', 'varchar','INT', 'TINYINT', 'datetime','text','double','decimal') 
ORDER BY line; 

HTH alguien en el futuro ... Por cierto vistas son también un guión aquí lo que puede tener que sacarlos de su código SQL última

+0

Si tiene una solución completa, probablemente debería agregarla a su pregunta para que otros la encuentren más fácil – Adrian

+1

¡no es perfecta, pero sí lo suficientemente cerca! – Rippo

+0

Para votar abajo, preguntándose por qué ha votado. cualquier comentario es bienvenido, gracias – Rippo

6

Puede cambiar el nombre de todos los nombres de tablas y columnas en minúsculas por aplicando la siguiente expresión regular para un volcado SQL (por ejemplo, el vertedero genera por mysqldump):

s/`\(\w\+\)`/\L&/g 

Esto funciona porque todos los nombres de tablas y columnas están envueltos por `` (invertidas). Es mejor hacerlo solo en el esquema, separado de los datos (solo trabaje con estructuras de tabla y luego haga las inserciones).

Para hacer esto en Vim, abra el volcado SQL y escriba el siguiente comando:

:%s/`\(\w\+\)`/\L&/g 

o hacerlo desde la línea de comandos usando sed:

sed 's/`\(\w\+\)`/\L&/g' input.sql > output.sql 

Si tiene que hacerlo repetidamente, almacene la expresión en un archivo de texto, e invoque de la siguiente manera:

sed -f regex.txt input.sql > output.sql 
+0

Esto me ayudó TANTO. ¡Gracias! – aendrew

+0

Gracias d3vid por la edición. Es muy útil ahora. – lepe

3

La solución propuesta por lepe es realmente la única forma segura de hacerlo. Los métodos de scripting son demasiado peligrosos, fáciles de exportar o procesan la definición de datos incorrecta. Todos los scripts de ejemplo anteriores omiten varios tipos de datos, por lo que están incompletos.

Hice un sqldump que coloca palos de retroceso alrededor de los nombres de tabla y columna, luego usé Notepad ++ para buscar en (`. *`) Y reemplazar con \ L \ 1. Eso hizo que todos mis nombres de tabla y columna aparecieran en minúsculas.

Luego hice una copia de seguridad de mi base de datos, borré todas las tablas y luego ejecuté mi archivo .sql para reconstruir. No me preocupé por hacer una estructura separada de los datos ya que no encontré ninguna ocurrencia del símbolo de retroceso en ninguno de mis datos.

En mi caso, necesito los nombres de mis columnas en minúsculas porque mi entorno de desarrollo convierte automáticamente first_name en First Name: como mi etiqueta de campo para la entrada de datos. Si los dejara como mayúsculas (que heredé), convertirían a FIRST NAME que no es lo que quiero, tendría que modificar todas mis etiquetas de campo.

Cuestiones relacionadas