SQL COMO falha consulta - Erro fatal na declaração preparada
Pergunta
Eu tenho o seguinte código:
$countQuery = "SELECT ARTICLE_NO FROM ? WHERE upper(ARTICLE_NAME) LIKE '% ? %'";
if ($numRecords = $con->prepare($countQuery)) {
$numRecords->bind_param("ss", $table, $brand);
$numRecords->execute();
$data = $con->query($countQuery) or die(print_r($con->error));
$rowcount = mysql_num_rows($data);
$rows = getRowsByArticleSearch($query, $table, $max);
$last = ceil($rowcount/$page_rows);
}
O que deve funcionar bem. No entanto eu recebo o erro que:
Você tem um erro em sua sintaxe SQL; verifique o manual que corresponde ao seu servidor MySQL versão para o direito de utilizar sintaxe próximo '? ONDE superior (ARTICLE_NAME) LIKE '%?%'' At line 1
Se eu colocar
SELECT ARTICLE_NO FROM AUCTIONS WHERE upper(ARTICLE_NAME) LIKE '% o %';
A consulta funciona bem. $ Tabela é definido acima e consulta é recebida de GET, e ambos são valores válidos corretas. Porque é que esta falha?
edit: mudar para:
$countQuery = "SELECT ARTICLE_NO FROM AUCTIONS1 WHERE upper(ARTICLE_NAME) LIKE '% ? %'";
if ($numRecords = $con->prepare($countQuery)) {
$numRecords->bind_param("s", $query);
resulta em erro:
Atenção: mysqli_stmt :: bind_param () [mysqli-stmt.bind-param]: O número de variáveis ??não coincidir com o número de parâmetros na declaração preparada em C: \ Program Files \ EasyPHP 3.0 \ www \ prog \ get_records. php na linha 38
Commands out of sync; você não pode executar este comando agora
onde como
$countQuery = "SELECT ARTICLE_NO FROM AUCTIONS1 WHERE upper(ARTICLE_NAME) LIKE ?";
if ($numRecords = $con->prepare($countQuery)) {
$numRecords->bind_param("s", "%".$query."%");
resultado em
Erro fatal: Não é possível passar parâmetros 2 por referência em C: \ Program Files \ EasyPHP 3.0 \ www \ prog \ get_records.php na linha 38
e por último
$countQuery = "SELECT ARTICLE_NO FROM AUCTIONS1 WHERE upper(ARTICLE_NAME) LIKE ? ";
if ($numRecords = $con->prepare($countQuery)) {
$numRecords->bind_param("s", $query);
dará apenas:
Commands out of sync; você não pode executar este comando agora
É impossível usar um paramter para uma statament COMO?
Solução
Para cláusula LIKE
, use o seguinte:
SELECT ARTICLE_NO FROM AUCTIONS1 WHERE upper(ARTICLE_NAME) LIKE CONCAT('%', ?, '%')
Como para o nome da tabela, é uma prática extremamente ruim ter nomes de tabelas como parâmetros.
Se por algum motivo você ainda precisa fazer isso, você precisa incorporá-lo no texto da consulta antes de preparar a consulta:
$countQuery = "SELECT ARTICLE_NO FROM $table_name WHERE upper(ARTICLE_NAME) LIKE CONCAT('%', ? ,'%')";
if ($numRecords = $con->prepare($countQuery)) {
$numRecords->bind_param("s", $brand);
$numRecords->execute();
$data = $con->query($countQuery) or die(print_r($con->error));
$rowcount = mysql_num_rows($data);
$rows = getRowsByArticleSearch($query, $table, $max);
$last = ceil($rowcount/$page_rows);
}
Outras dicas
Você emitiu
mysqli_free_result($result);
após a última consulta? Isso é o comando fora de erro de sincronização.
Isso deve funcionar no entanto
$countQuery = "SELECT ARTICLE_NO FROM AUCTIONS1 WHERE upper(ARTICLE_NAME) LIKE ?";
if ($numRecords = $con->prepare($countQuery)) {
$numRecords->bind_param("s", "%".$query."%");
Quer saber o que está na variável $ query. Tente fazer isso em vez
$query = '%'.$query.'%';
$numRecords->bind_param("s", $query);
Tente o seguinte em vez disso:
$countQuery = "SELECT ARTICLE_NO FROM ? WHERE upper(ARTICLE_NAME) LIKE ?";
if ($numRecords = $con->prepare($countQuery)) {
$numRecords->bind_param("ss", $table, "%$brand%");
$numRecords->execute();
$data = $con->query($countQuery) or die(print_r($con->error));
$rowcount = mysql_num_rows($data);
$rows = getRowsByArticleSearch($query, $table, $max);
$last = ceil($rowcount/$page_rows);
}
AFAIK você não pode usar espaços reservados para identificadores com mysqli e preparar declarações. Então você tem que interpolar manualmente o tablename na consulta.