Guia Completo sobre a Função mysqli_sqlstate no PHP
Aprenda como mysqli_sqlstate() retorna códigos SQLSTATE ANSI/ISO no PHP, como difere de mysqli_errno() e o uso no modo de exceção.
Ao trabalhar com MySQL no PHP por meio da extensão mysqli, você precisa de uma forma confiável de descobrir por que uma consulta falhou. A função mysqli_sqlstate() retorna o código de erro SQLSTATE da operação MySQL executada mais recentemente — um código padronizado e portátil que indica a categoria do erro.
Este guia explica o que é SQLSTATE, como mysqli_sqlstate() difere do mysqli_errno() específico do MySQL, os códigos que você encontrará com mais frequência e como usá-la corretamente (inclusive no modo moderno baseado em exceções do PHP).
O que é SQLSTATE?
SQLSTATE é um código de erro de cinco caracteres definido pelo padrão ANSI/ISO SQL. Por fazer parte do padrão em vez de ser uma invenção do MySQL, o mesmo código significa aproximadamente a mesma coisa em diferentes mecanismos de banco de dados, tornando-o mais portátil do que números de erro específicos de cada fornecedor.
Os cinco caracteres são divididos em duas partes:
- Os dois primeiros caracteres são a classe do erro. Por exemplo, a classe
00significa sucesso,01significa um aviso e42significa uma violação de sintaxe ou regra de acesso. - Os últimos três caracteres são a subclasse, que detalha ainda mais o problema.
Assim, 42S02 ("tabela base ou visão não encontrada") pertence à classe 42 (violação de sintaxe/acesso) com a subclasse S02.
Sintaxe
mysqli_sqlstate(mysqli $connection): stringmysqli_sqlstate() recebe um único argumento — o objeto de conexão retornado por mysqli_connect() — e retorna uma string:
- Uma string preenchida com zeros
"00000"quando a última operação foi bem-sucedida. - Um código de cinco caracteres como
"42S02"quando ocorreu um erro.
No estilo orientado a objetos, isso é o método
$connection->sqlstate.
SQLSTATE vs. mysqli_errno: qual usar?
Essas duas funções respondem perguntas diferentes, e muitas vezes você vai querer ambas:
| Função | Retorna | Natureza |
|---|---|---|
mysqli_sqlstate() | Uma string de 5 caracteres como "42S02" | Padrão ANSI/ISO — portátil entre bancos de dados |
mysqli_errno() | Um inteiro como 1146 | Específico do MySQL — mais granular, mas não portátil |
mysqli_error() | Uma mensagem legível por humanos | O texto descritivo para registro/depuração |
Regra geral: use mysqli_sqlstate() para ramificar sua lógica quando quiser código que sobreviva a uma migração de banco de dados, e recorra a mysqli_errno() quando precisar de uma distinção específica do MySQL. Use mysqli_error() para a mensagem que você registra em log.
Um exemplo completo
O trecho abaixo conecta, executa uma consulta em uma tabela que não existe e exibe todos os três diagnósticos para que você possa ver como eles se relacionam:
<?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 existObserve como o SQLSTATE portátil (42S02) e o número de erro específico do MySQL (1146) descrevem o mesmo problema em dois níveis de detalhe.
Códigos SQLSTATE comuns
Estes são os códigos que você provavelmente irá tratar no dia a dia com PHP/MySQL:
| SQLSTATE | Significado |
|---|---|
00000 | Sucesso — sem erro |
23000 | Violação de restrição de integridade (ex.: chave duplicada, falha de chave estrangeira) |
42000 | Erro de sintaxe ou violação de regra de acesso |
42S02 | Tabela base ou visão não encontrada |
42S22 | Coluna não encontrada |
HY000 | Erro geral (código genérico quando nenhum código específico se aplica) |
08S01 | Falha de comunicação / link de conexão |
Ramificar nesses códigos permite reagir de forma significativa — por exemplo, tratar um erro de chave duplicada 23000 como "este registro já existe" em vez de uma falha 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 com o modo de exceção
O PHP moderno (8.1+) habilita o relatório de erros do MySQL por padrão, então uma consulta com falha lança uma mysqli_sql_exception em vez de retornar false. Nesse modo, você lê o SQLSTATE pelo método getSqlState() da exceção, em vez de chamar mysqli_sqlstate() depois:
<?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();
}Se você chamar
mysqli_sqlstate()diretamente após uma exceção já ter sido capturada, ainda funciona — mas dentro de um blocotry/catch, ler o código do objeto de exceção é mais limpo e evita re-consultar o estado da conexão.
Armadilhas
- Reflete apenas a última operação. Cada nova consulta sobrescreve o SQLSTATE anterior. Leia-o imediatamente após a chamada que lhe interessa — antes de executar qualquer outra coisa na mesma conexão.
"00000"é sucesso, não um erro. Não trate um retorno não vazio como falha; uma operação bem-sucedida retorna a string de zeros, não"".- Uma conexão com falha não tem SQLSTATE. Se o próprio
mysqli_connect()falhar, não há objeto de conexão para consultar; usemysqli_connect_error()para problemas de conexão.
Conclusão
mysqli_sqlstate() fornece o código SQLSTATE portátil e baseado em padrões para a última operação MySQL, complementando o mysqli_errno() específico do MySQL e o mysqli_error() legível por humanos. Use SQLSTATE para ramificar quando quiser tratamento de erros agnóstico ao banco de dados, mude para o getSqlState() da exceção ao rodar no modo de exceção padrão do PHP, e sempre leia o código logo após a operação que ele descreve.