Prueba el SQL generado por IA con pequeños juegos de datos de SQLite
En esta página
El SQL generado por IA puede ejecutarse sin errores y aun así omitir a clientes que nunca hicieron pedidos. Prueba sus totales con una base de datos pequeña de respuestas conocidas.
Crea una comprobación local de corrección con Python y datos sintéticos de SQLite. No necesitas una cuenta de IA, paquetes ni conexión a producción. Estas consultas escritas a mano prueban el comprobador, no un producto de IA.
1. Define el informe antes de pedirlo a la IA
Pide a tu asistente de IA autorizado:
Escribe un único SELECT de SQLite con customers(id, name) y orders(id, customer_id, status). Devuelve el ID de cada cliente y su número de pedidos pagados, incluido cero. Un pedido está pagado solo cuando status es igual a ‘paid’. Ordena por ID de cliente. Devuelve únicamente SQL.
Proporciona el esquema y ejemplos sintéticos, no registros privados de clientes. Para repasar las cláusulas, consulta nuestra guía para leer consultas SQL.
Define las filas esperadas antes de revisar el SQL generado. No dejes que el modelo decida sus propias respuestas de referencia.
2. Elige datos que revelen errores plausibles
Nuestro juego de prueba es un conjunto de datos pequeño y reutilizable:
| ID de cliente | Pedidos en los datos de prueba | Número esperado de pedidos pagados |
|---|---|---|
| 1 | Dos pagados y uno cancelado | 2 |
| 2 | Ninguno | 0 |
| 3 | Uno cancelado | 0 |
El segundo cliente detecta la pérdida de filas sin coincidencias; el tercero detecta filtros que eliminan clientes sin pedidos válidos. El primero detecta consultas que cuentan todos los pedidos en lugar de los pagados.
Un LEFT JOIN conserva a los clientes sin coincidencias. Mantén la condición de estado en ON: un filtro de la tabla derecha en WHERE puede eliminar las filas completadas con nulos, como explica la documentación de SELECT de SQLite. Además, COUNT(o.id) ignora nulos, mientras que COUNT(*) cuenta filas, incluida la fila de relleno de un cliente sin coincidencias. Consulta las definiciones de agregados de SQLite.
3. Ejecuta el comprobador y sus controles negativos
Guarda este código como check_ai_sql.py. Usa Python 3.10 o posterior con el módulo sqlite3 de la biblioteca estándar. La documentación de conexiones de Python describe las bases de datos :memory:.
import sqlite3
import sys
from pathlib import Path
REFERENCE = """
SELECT c.id, COUNT(o.id) AS paid_orders
FROM customers AS c
LEFT JOIN orders AS o
ON o.customer_id = c.id AND o.status = 'paid'
GROUP BY c.id
ORDER BY c.id;
"""
EXPECTED = [(1, 2), (2, 0), (3, 0)]
if len(sys.argv) > 2:
raise SystemExit("usage: python3 check_ai_sql.py [candidate.sql]")
db = sqlite3.connect(":memory:")
try:
db.executescript("""
CREATE TABLE customers(id INTEGER PRIMARY KEY, name TEXT NOT NULL);
CREATE TABLE orders(
id INTEGER PRIMARY KEY,
customer_id INTEGER NOT NULL,
status TEXT NOT NULL
);
INSERT INTO customers VALUES (1, 'Ada'), (2, 'Luis'), (3, 'Mina');
INSERT INTO orders VALUES
(101, 1, 'paid'), (102, 1, 'paid'),
(103, 1, 'cancelled'), (104, 3, 'cancelled');
""")
controls = {
"inner_join": REFERENCE.replace("LEFT JOIN", "JOIN"),
"count_star": REFERENCE.replace("COUNT(o.id)", "COUNT(*)"),
"where_filter": REFERENCE.replace(
"ON o.customer_id = c.id AND o.status = 'paid'",
"ON o.customer_id = c.id\nWHERE o.status = 'paid'",
),
}
for name, query in controls.items():
rows = db.execute(query).fetchall()
passed = rows == EXPECTED
print(f"{name}: {'PASS' if passed else 'FAIL'} {rows}")
if passed:
raise RuntimeError(f"fixture failed to catch {name}")
query = REFERENCE
if len(sys.argv) == 2:
query = Path(sys.argv[1]).read_text(encoding="utf-8")
rows = db.execute(query).fetchall()
passed = rows == EXPECTED
print(f"candidate: {'PASS' if passed else 'FAIL'} {rows}")
raise SystemExit(0 if passed else 1)
finally:
db.close()
Ejecuta primero la consulta de referencia integrada:
python3 check_ai_sql.py
Salida esperada:
inner_join: FAIL [(1, 2)]
count_star: FAIL [(1, 2), (2, 1), (3, 1)]
where_filter: FAIL [(1, 2)]
candidate: PASS [(1, 2), (2, 0), (3, 0)]
Las tres líneas FAIL son controles negativos deliberados: deben rechazarse las consultas con pequeños errores. La referencia supera la prueba con código de salida 0; las consultas rechazadas siguen siendo inaceptables.
4. Comprueba una respuesta de IA revisada
Lee primero el SQL generado. Guarda únicamente su SELECT revisado en UTF-8 como candidate.sql, sin delimitadores Markdown. Después ejecuta:
python3 check_ai_sql.py candidate.sql
Los controles negativos siguen ejecutándose. La consulta candidata debe devolver exactamente [(1, 2), (2, 0), (3, 0)] en ese orden. Una discrepancia imprime candidate: FAIL y termina con código 1; los errores SQL también interrumpen la ejecución con un código distinto de cero. Copiar el SELECT de referencia del script en este archivo reproduce el resultado correcto.
Esto comprueba filas, cantidades y orden, no alias de columnas, velocidad ni corrección universal. Una base de datos en memoria no es un entorno de seguridad aislado. No ejecutes SQL arbitrario sin revisar, adjuntes archivos reales, cargues extensiones ni adaptes este ejemplo para conectarlo a una base de datos en producción.
5. Resuelve problemas y amplía las pruebas
- Faltan clientes con cantidad cero: revisa el tipo de unión y la ubicación del filtro de estado.
- Los ceros se convierten en unos: comprueba si
COUNT(*)está contando filas sin coincidencias. - Valores correctos, orden incorrecto: exige el
ORDER BYindicado; no ocultes el fallo ordenando solo el resultado en Python. - Falta el módulo
sqlite3: usa una distribución de Python compilada con soporte para SQLite; este ejemplo no tiene una dependencia separada de pip. - El dialecto de producción es distinto: repite las pruebas en el motor real sobre tablas sintéticas desechables antes de aprobar una consulta.
Añade casos basados en fallos reales, como nombres visibles duplicados o tablas adicionales que multipliquen las filas al unirlas. Reserva otro juego de datos no visto para la revisión final después de cambiar la petición. Para resúmenes más complejos, consulta nuestra guía de agregación condicional.
Conclusión práctica
Pide la consulta a la IA, pero decide tú el resultado esperado. Los datos pequeños y los controles con errores deliberados revelan fallos que una comprobación de sintaxis no detecta. Superar este ejemplo justifica seguir probando, no ejecutar la consulta en producción.
Artículos relacionados
Evalúa la clasificación de incidencias con una matriz de confusión
Evalúa transcripciones de IA con la tasa de error por palabra
Las Reglas Ocultas: Entendiendo las Restricciones de Integridad en SQL
Modificando Tablas: Cómo Añadir una Nueva Columna en SQL
Comandos TCL en SQL: Asegurando Transacciones Confiables e Integridad de Datos
Los 10 Mejores Canales de YouTube para Dominar SQL a Tu Propio Ritmo
Usa Alias en SQL como un Profesional: No Más Consultas Desordenadas
Cómo evaluar la recuperación RAG con Recall@k y MRR
Comando Grant en SQL: Cómo Asignar Permisos de Usuario Precisos de Forma Segura
Diseña Bases de Datos Más Inteligentes: Guía Práctica para la Normalización en SQL
Cómo la Agregación Condicional Hace que SQL Sea Más Inteligente
Vistas en SQL: Una Perspectiva Más Inteligente de Tus Datos
Últimos artículos
Evalúa campos extraídos por IA con precisión y recall de coincidencia exacta
Comprueba las rutas propuestas por IA antes de escribir con Python
Evita actualizaciones de IA obsoletas con un control de versión en SQLite
Comprueba las dependencias de tareas de IA antes de programarlas con Python
Revisa los cambios JSON de la IA con una lista de campos permitidos
Combina resultados RAG con fusión de rangos recíprocos
Comprueba las horas de calendario de IA antes de crear eventos
Comprueba citas textuales de IA con fuentes locales y Python
Comprueba las cifras de resúmenes de IA con una tabla de referencia
Elige umbrales de revisión de IA con cobertura y tasas de error
Comprueba los marcadores de traducciones de IA con Python