2010-03-25 24 views
7

Así que tenemos muchas rutinas que salen de la exportación. A menudo necesitamos sacarlos en CLI, hacer cambios y volver a generarlos. Sí, algunos de estos son administrados por diferentes personas y se requiere un mejor control de cambios, pero por ahora esta es la situación.MySQL - mysqldump --rutinas solo para exportar 1 procedimiento almacenado (por nombre) y no todas las rutinas

Si hago:

mysqldump --routines --no-create-info --no-data --no-create-db 

entonces bien, tengo 200 funciones. Necesito revisar un archivo para encontrar el que quiero o el que quiero.

¿Hay de todos modos para las rutinas mysqldump que quiero que haya para las tablas?

Respuesta

13

Otra forma de hacerlo sería la siguiente. Ten en cuenta, sin embargo, que usted tiene que tener privilegios de root en la base de datos de destino con el fin de importar filas en mysql.proc:

mysqldump --compact --no-create-info --where="db='yourdatabasename' AND type='PROCEDURE' AND name IN ('yoursp1', 'yoursp2')" --databases mysql --tables proc 
+0

Para restaurar el guión creado por este vertedero, que necesita para calificar la referencia de tabla 'proc' a mysql.proc manualmente. Sin embargo, en general, considero que el resultado de este método es mucho más flexible que el método tradicional mysqldump --routines. ¡Gracias! – ExStackChanger

4

Es posible volcar una sola función o procedimiento utilizando el comando que Ike Walker mencionó , pero los comandos SHOW CREATE PROCEDURE y SHOW CREATE FUNCTION no permiten seleccionar solo unas pocas columnas de la salida.

Aquí está un ejemplo de una línea de comandos por lotes de Windows para volcar un procedimiento único, utilizando la tabla de sistema mysql.proc:

mysql --defaults-extra-file=myconfig.cnf --skip-column-names --raw --batch mydatabase -e "SELECT CONCAT('DELIMITER $$\nCREATE PROCEDURE `', specific_name, '`(', param_list, ') AS \n', body_utf8, ' $$\nDELIMITER ;\n') AS `stmt` FROM `mysql`.`proc` WHERE `db` = 'mydatabase' AND specific_name = 'myprocedure';" 1> myprocedure.sql 

Esto redireccionará la salida de MySQL en el archivo myprocedure.sql .

La opción --batch le dice al cliente mysql que elimine los bordes de la tabla de la salida. La opción --skip-column-names elimina los encabezados de columna de la salida. La opción --raw le dice a MySQL que no escape de los caracteres especiales en la salida, manteniendo las líneas nuevas como están en vez de reemplazarlas por \n.

Y si quieres descargar todos los procedimientos en diferentes archivos, en este ejemplo debería funcionar por lotes:

volcado-procedures.bat

@echo off 

REM set the target database 
set database=mydatabase 

REM set the connection configuration file 
set auth=--defaults-extra-file=myconfig.cnf 

REM set the routine type you want to dump 
set routine_type=PROCEDURE 

set list_file=%routine_type%S.csv 

if "%routine_type%"=="PROCEDURE" (
set ending=AS 
) 
if "%routine_type%"=="FUNCTION" (
set ending=RETURNS ', `returns`, ' 
) 

echo Dumping %routine_type% list to %list_file% 
mysql %auth% --skip-column-names --raw %database% -e "SELECT routine_name FROM INFORMATION_SCHEMA.ROUTINES WHERE ROUTINE_SCHEMA = DATABASE() AND ROUTINE_TYPE = '%routine_type%';" 1> %list_file% 

for /f "tokens=*" %%a in (%list_file%) do (
    echo Dumping %routine_type% %%a 
    mysql %auth% --skip-column-names --raw --batch %database% -e "SELECT CONCAT('DELIMITER $$\nCREATE PROCEDURE `', specific_name, '`(', param_list, ') %ending% \n', body_utf8, ' $$\nDELIMITER ;\n') AS `stmt` FROM `mysql`.`proc` WHERE `db` = '%database%' AND specific_name = '%%a';" 1> %%a.sql 
) 

Funciona en 2 etapas, donde primero vuelca la lista de todos los procedimientos en el archivo procedures.csv, y luego itera en cada línea y usa los nombres de los procedimientos para volcar cada procedimiento en un archivo diferente.

En este ejemplo, también estoy usando la opción --defaults-extra-file, donde algunos parámetros de configuración se establecen en un archivo diferente, y permite invocar el comando sin necesidad de escribir la contraseña cada vez o escribiendo la contraseña dentro del lote mismo. He creado un archivo con este contenido

myconfig.cnf

[client] 
host=localhost 
port=3306 

user=myusername 
password=mypassword 

Esta solución también funciona con la función, la definición de la variable routine_type a:

set routine_type=FUNCTION 
+0

donde define esta variable% header% –

+0

@ Bill.Zhuang gracias por la observación. Esa variable era de una versión anterior donde definí el nombre de la columna en otra parte de la secuencia de comandos. Probé esta nueva solución solo reemplazando el nombre de la base de datos y el archivo por defecto, y funciona. – carlososuna86

+0

Por alguna razón, esto pierde toda la salida que se escapa dentro de cadenas en el cuerpo del procedimiento almacenado. – badbod99

0

He escrito la solución dentro de bash .

Por un procedimiento

mysql -NB -u root my_database -e 'show create procedure `myProcedure`' |\ 
xargs -n 1 -d '\t' echo |\ 
egrep '^CREATE' |\ 
xargs --null echo -e > 

Para todos los procedimientos

mysql -NB -u root -e 'SELECT ROUTINE_NAME FROM INFORMATION_SCHEMA.ROUTINES WHERE ROUTINE_SCHEMA = "my_database" AND ROUTINE_TYPE = "PROCEDURE"' |\ 
xargs -n 1 -I {} mysql -NB -u root my_database -e 'show create procedure `{}`' |\ 
xargs -n 1 -d '\t' echo |\ 
egrep '^CREATE' |\ 
xargs --null echo -e 
Cuestiones relacionadas