Ejecutar archivos SQL es una de las tareas más frecuentes en la administración de MySQL. Ya sea para aplicar migraciones de esquema, importar datos de respaldo, ejecutar scripts de mantenimiento o poblar una base de datos de desarrollo con datos de prueba, saber cómo ejecutar archivos SQL de forma eficiente y controlada es una habilidad esencial. MySQL ofrece varias formas de hacerlo, cada una con sus ventajas según el contexto.

Ejecutar desde la línea de comandos con redirección

La forma más directa de ejecutar un archivo SQL es redirigir su contenido al cliente mysql usando el operador < de la shell:

mysql -u admin -p tienda_online < /scripts/migracion_v2.sql
Enter password: ********

Este comando conecta al servidor como el usuario admin, selecciona la base de datos tienda_online y ejecuta todas las sentencias contenidas en el archivo migracion_v2.sql. Si todas las sentencias se ejecutan correctamente, el comando termina sin mostrar salida. Los errores, si los hay, se imprimen en stderr.

Si utilizas login-paths configurados con mysql_config_editor, el comando es aún más limpio:

mysql --login-path=produccion tienda_online < /scripts/migracion_v2.sql

Puedes omitir el nombre de la base de datos si el archivo SQL incluye la sentencia USE al principio:

-- migracion_v2.sql
USE tienda_online;
 
ALTER TABLE productos ADD COLUMN peso_kg DECIMAL(8,2) DEFAULT NULL;
ALTER TABLE productos ADD INDEX idx_peso (peso_kg);

Ejecutar con el comando SOURCE

Cuando ya estás dentro de una sesión interactiva de MySQL, puedes ejecutar un archivo SQL con el comando SOURCE o su abreviatura \.:

mysql> SOURCE /scripts/migracion_v2.sql;

O la forma abreviada:

mysql> \. /scripts/migracion_v2.sql

La diferencia con la redirección desde la shell es que SOURCE se ejecuta dentro de una sesión ya establecida. Esto significa que puedes preparar el contexto antes de ejecutar el archivo:

-- Seleccionar la base de datos
USE tienda_online;
 
-- Desactivar verificación de claves foráneas temporalmente
SET FOREIGN_KEY_CHECKS = 0;
 
-- Ejecutar el archivo
SOURCE /scripts/datos_iniciales.sql;
 
-- Reactivar verificación de claves foráneas
SET FOREIGN_KEY_CHECKS = 1;

Esta técnica es particularmente útil cuando el archivo SQL inserta datos que tienen dependencias circulares de claves foráneas.

Capturar la salida en un archivo

Cuando el archivo SQL contiene consultas SELECT o sentencias que producen salida, puedes redirigir los resultados a un archivo:

mysql -u admin -p tienda_online < /scripts/reporte_inventario.sql \
  > /reportes/inventario_2025.txt

Si el archivo reporte_inventario.sql contiene:

SELECT
  c.nombre AS categoria,
  COUNT(*) AS productos,
  SUM(p.stock) AS stock_total,
  ROUND(AVG(p.precio), 2) AS precio_promedio
FROM productos p
JOIN categorias c ON p.categoria_id = c.id
GROUP BY c.nombre
ORDER BY stock_total DESC;

El archivo de salida contendrá los resultados en formato tabulado. Para obtener los resultados separados por tabuladores (útil para importar en una hoja de cálculo):

mysql -u admin -p --batch tienda_online < /scripts/reporte_inventario.sql \
  > /reportes/inventario.tsv

La opción --batch elimina los bordes decorativos de la tabla y usa tabuladores como separadores.

Ejecutar con control de errores

Por defecto, cuando MySQL encuentra un error en un archivo SQL, muestra el mensaje de error y continúa ejecutando las sentencias siguientes. Este comportamiento puede ser problemático en migraciones donde el orden importa. Para redirigir errores a un archivo de log:

mysql -u admin -p tienda_online < /scripts/migracion.sql \
  2> /logs/errores_migracion.log

En este caso, los errores se redirigen al archivo de log mientras la salida estándar sigue en la terminal. Si quieres que el proceso se detenga al primer error en un script de shell, puedes verificar el código de salida:

#!/bin/bash
mysql --login-path=produccion tienda_online \
  < /scripts/migracion_v3.sql 2> /tmp/errores.log
 
if [ $? -ne 0 ]; then
  echo "ERROR: La migración falló. Revisar /tmp/errores.log"
  cat /tmp/errores.log
  exit 1
fi
 
echo "Migración completada exitosamente."

Dentro de un archivo SQL, puedes usar comentarios para documentar cada sección y facilitar la depuración si algo falla:

-- =============================================
-- Migración v3: Sistema de descuentos
-- Fecha: 2025-03-18
-- =============================================
 
-- Paso 1: Crear tabla de descuentos
CREATE TABLE descuentos (
  id INT AUTO_INCREMENT PRIMARY KEY,
  codigo VARCHAR(20) UNIQUE NOT NULL,
  porcentaje DECIMAL(5,2) NOT NULL,
  fecha_inicio DATE NOT NULL,
  fecha_fin DATE NOT NULL,
  usos_maximos INT DEFAULT NULL,
  usos_actuales INT DEFAULT 0,
  activo TINYINT(1) DEFAULT 1,
  creado_en TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
 
-- Paso 2: Agregar columna de descuento a pedidos
ALTER TABLE pedidos ADD COLUMN descuento_id INT DEFAULT NULL;
ALTER TABLE pedidos ADD CONSTRAINT fk_pedido_descuento
  FOREIGN KEY (descuento_id) REFERENCES descuentos(id);
 
-- Paso 3: Insertar descuentos iniciales
INSERT INTO descuentos
  (codigo, porcentaje, fecha_inicio, fecha_fin, usos_maximos)
VALUES
  ('BIENVENIDA10', 10.00, '2025-01-01', '2025-12-31', 1000),
  ('VERANO25', 25.00, '2025-06-01', '2025-08-31', 500);

Caso práctico: importar un archivo SQL grande

Cuando necesitas importar un archivo SQL grande (por ejemplo, un respaldo de varios gigabytes), hay opciones que aceleran significativamente el proceso:

mysql --login-path=produccion \
  --max-allowed-packet=512M \
  --net-buffer-length=32768 \
  tienda_online < /backups/tienda_online_20250318.sql

La opción --max-allowed-packet aumenta el tamaño máximo de los paquetes de red, necesario cuando el archivo contiene sentencias INSERT con muchos registros agrupados. La opción --net-buffer-length incrementa el buffer de red.

Dentro del propio archivo SQL de respaldo (generado por mysqldump), puedes incluir directivas que optimizan la importación:

SET @OLD_AUTOCOMMIT = @@AUTOCOMMIT;
SET AUTOCOMMIT = 0;
SET @OLD_UNIQUE_CHECKS = @@UNIQUE_CHECKS;
SET UNIQUE_CHECKS = 0;
SET @OLD_FOREIGN_KEY_CHECKS = @@FOREIGN_KEY_CHECKS;
SET FOREIGN_KEY_CHECKS = 0;
 
-- ... miles de INSERT aquí ...
 
COMMIT;
SET AUTOCOMMIT = @OLD_AUTOCOMMIT;
SET UNIQUE_CHECKS = @OLD_UNIQUE_CHECKS;
SET FOREIGN_KEY_CHECKS = @OLD_FOREIGN_KEY_CHECKS;

Desactivar el autocommit, las verificaciones de unicidad y las claves foráneas durante la importación puede reducir el tiempo de una importación grande de horas a minutos.

Caso práctico: script de inicialización para desarrollo

En equipos de desarrollo, es habitual tener un script que crea la base de datos completa con datos de prueba. Puedes estructurarlo como un archivo SQL maestro que llama a otros archivos:

-- init_desarrollo.sql
-- Script maestro de inicialización
 
-- Crear la base de datos
DROP DATABASE IF EXISTS tienda_dev;
CREATE DATABASE tienda_dev
  CHARACTER SET utf8mb4
  COLLATE utf8mb4_unicode_ci;
USE tienda_dev;
 
-- Crear esquema (tablas, índices, constraints)
SOURCE /proyecto/sql/01_esquema.sql;
 
-- Crear procedimientos almacenados y funciones
SOURCE /proyecto/sql/02_procedimientos.sql;
 
-- Insertar datos de referencia (categorías, roles, etc.)
SOURCE /proyecto/sql/03_datos_referencia.sql;
 
-- Insertar datos de prueba
SOURCE /proyecto/sql/04_datos_prueba.sql;
 
-- Verificar
SELECT 'Inicialización completada' AS estado;
SELECT TABLE_NAME, TABLE_ROWS
FROM information_schema.TABLES
WHERE TABLE_SCHEMA = 'tienda_dev'
ORDER BY TABLE_NAME;

Para ejecutarlo:

mysql --login-path=desarrollo < /proyecto/sql/init_desarrollo.sql

Este enfoque modular permite reutilizar los archivos individuales (por ejemplo, ejecutar solo el esquema sin los datos de prueba) y facilita la revisión de código en equipo.

Ejecutar archivos SQL es una habilidad que usarás a diario como administrador de bases de datos. En el siguiente artículo profundizaremos en las variables de sesión, que permiten ajustar el comportamiento de MySQL para cada conexión individual.

Escrito por Eduardo Lázaro