Guía completa sobre la función mysqli_sqlstate en PHP
Aprende cómo mysqli_sqlstate() devuelve códigos SQLSTATE ANSI/ISO en PHP, sus diferencias con mysqli_errno() y el uso en modo excepción.
Cuando trabajas con MySQL en PHP a través de la extensión mysqli, necesitas una forma fiable de saber por qué falló una consulta. La función mysqli_sqlstate() devuelve el código de error SQLSTATE de la operación MySQL ejecutada más recientemente — un código estandarizado y portable que indica la categoría del error.
Esta guía explica qué es SQLSTATE, en qué se diferencia mysqli_sqlstate() de la función específica de MySQL mysqli_errno(), los códigos que encontrarás con más frecuencia y cómo utilizarla correctamente (incluido el modo moderno de PHP basado en excepciones).
¿Qué es SQLSTATE?
SQLSTATE es un código de error de cinco caracteres definido por el estándar ANSI/ISO SQL. Al formar parte del estándar y no ser una invención de MySQL, el mismo código significa aproximadamente lo mismo en distintos motores de base de datos, lo que lo hace más portable que los números de error específicos de un proveedor.
Los cinco caracteres se dividen en dos partes:
- Los dos primeros caracteres corresponden a la clase del error. Por ejemplo, la clase
00significa éxito,01significa advertencia y42indica una violación de sintaxis o de regla de acceso. - Los tres últimos caracteres son la subclase, que acota el problema con más detalle.
Así, 42S02 ("tabla base o vista no encontrada") pertenece a la clase 42 (violación de sintaxis/acceso) con la subclase S02.
Sintaxis
mysqli_sqlstate(mysqli $connection): stringmysqli_sqlstate() recibe un único argumento — el objeto de conexión devuelto por mysqli_connect() — y retorna un string:
- El string vacío-pero-relleno de ceros
"00000"cuando la última operación tuvo éxito. - Un código de cinco caracteres como
"42S02"cuando se produjo un error.
En estilo orientado a objetos esto equivale al método
$connection->sqlstate.
SQLSTATE vs. mysqli_errno: ¿cuál deberías usar?
Estas dos funciones responden preguntas distintas, y a menudo querrás ambas:
| Función | Devuelve | Naturaleza |
|---|---|---|
mysqli_sqlstate() | Un string de 5 caracteres como "42S02" | Estándar ANSI/ISO — portable entre bases de datos |
mysqli_errno() | Un entero como 1146 | Específico de MySQL — más granular, pero no portable |
mysqli_error() | Un mensaje legible por humanos | El texto descriptivo para registro y depuración |
Regla general: ramifica tu lógica con mysqli_sqlstate() cuando quieras código que sobreviva una migración de base de datos, y recurre a mysqli_errno() cuando necesites una distinción específica de MySQL. Usa mysqli_error() para el mensaje que registres en el log.
Un ejemplo completo
El fragmento de código siguiente se conecta, ejecuta una consulta sobre una tabla que no existe e imprime los tres diagnósticos para que puedas ver cómo se relacionan:
<?php
$connection = mysqli_connect('localhost', 'user', 'password', 'mydatabase');
if (!$connection) {
die('Connection failed: ' . mysqli_connect_error());
}
$sql = "SELECT * FROM table_that_does_not_exist";
if (mysqli_query($connection, $sql)) {
echo "Query executed successfully.";
} else {
echo "SQLSTATE: " . mysqli_sqlstate($connection) . "\n";
echo "Errno: " . mysqli_errno($connection) . "\n";
echo "Message: " . mysqli_error($connection) . "\n";
}
// Typical output:
// SQLSTATE: 42S02
// Errno: 1146
// Message: Table 'mydatabase.table_that_does_not_exist' doesn't existObserva cómo el SQLSTATE portable (42S02) y el número de error específico de MySQL (1146) describen el mismo problema con dos niveles de detalle.
Códigos SQLSTATE más comunes
Estos son los códigos que más probablemente tendrás que gestionar en el trabajo diario con PHP/MySQL:
| SQLSTATE | Significado |
|---|---|
00000 | Éxito — sin error |
23000 | Violación de restricción de integridad (p. ej., clave duplicada, fallo de clave foránea) |
42000 | Error de sintaxis o violación de regla de acceso |
42S02 | Tabla base o vista no encontrada |
42S22 | Columna no encontrada |
HY000 | Error general (comodín cuando no aplica ningún código específico) |
08S01 | Fallo de enlace de comunicación/conexión |
Ramificar sobre estos códigos te permite reaccionar de forma significativa — por ejemplo, tratar un error de clave duplicada 23000 como "este registro ya existe" en lugar de como un fallo fatal:
<?php
$sql = "INSERT INTO users (email) VALUES ('[email protected]')";
if (!mysqli_query($connection, $sql)) {
if (mysqli_sqlstate($connection) === '23000') {
echo "That email address is already registered.";
} else {
echo "Unexpected database error: " . mysqli_error($connection);
}
}Uso con el modo excepción
El PHP moderno (8.1+) activa el reporte de errores de MySQL por defecto, por lo que una consulta fallida lanza una mysqli_sql_exception en lugar de devolver false. En ese modo, lees el SQLSTATE desde el método getSqlState() de la excepción en lugar de llamar a mysqli_sqlstate() a posteriori:
<?php
mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);
try {
$connection = mysqli_connect('localhost', 'user', 'password', 'mydatabase');
mysqli_query($connection, "SELECT * FROM missing_table");
} catch (mysqli_sql_exception $e) {
echo "SQLSTATE: " . $e->getSqlState() . "\n"; // e.g. 42S02
echo "Code: " . $e->getCode() . "\n"; // e.g. 1146
echo "Message: " . $e->getMessage();
}Si llamas a
mysqli_sqlstate()directamente después de que ya se haya capturado una excepción, seguirá funcionando — pero dentro de un bloquetry/catch, leer el código desde el objeto excepción es más limpio y evita volver a consultar el estado de la conexión.
Consideraciones importantes
- Solo refleja la última operación. Cada nueva consulta sobreescribe el SQLSTATE anterior. Léelo inmediatamente después de la llamada que te interesa — antes de ejecutar cualquier otra cosa en la misma conexión.
"00000"es éxito, no un error. No trates un valor de retorno no vacío como un fallo; una operación exitosa devuelve el string de todos ceros, no"".- Una conexión fallida no tiene SQLSTATE. Si
mysqli_connect()falla, no hay objeto de conexión que consultar, así que usamysqli_connect_error()para los problemas de conexión.
Conclusión
mysqli_sqlstate() te proporciona el código SQLSTATE portable y basado en estándares para la última operación MySQL, complementando la función específica de MySQL mysqli_errno() y el mensaje legible mysqli_error(). Ramifica con SQLSTATE cuando quieras un manejo de errores independiente de la base de datos, utiliza getSqlState() de la excepción cuando trabajes en el modo excepción predeterminado de PHP, y lee siempre el código justo después de la operación que describe.