Pregunta

Tengo problemas para ejecutar una declaración preparada a través de mysqli.

Primero estaba obteniendo errores de sincronización de comandos. Estoy almacenando el resultado y cerrando la conexión, y he dejado de recibir este error, así que espero que el problema se haya detenido.

Sin embargo, el error en mi error de sintaxis de SQL, que estaba funcionando bien mientras los comandos no estaban sincronizados, ha vuelto a aparecer. Aquí está mi código actual:

He intentado muchos enfoques diferentes para corregir este error de Snytax, desde el uso de CONCAT, que se comenta en su defecto, desde la asignación de signos de% a la variable antes de vincular, etc., nada funciona.

Intentando usar:

$numRecords->bind_param("s",  "%".$brand."%");

Resulta en un error que pasa por referencia.

<?php
$con = mysqli_connect("localhost", "blah", "blah", "blah");
if (!$con) {
    echo "Can't connect to MySQL Server. Errorcode: %s\n". mysqli_connect_error();
    exit;
}
$con->query("SET NAMES 'utf8'");
$brand = "o";
$brand = "% ".$brand." %";
echo "\n".$brand;
$countQuery = "SELECT ARTICLE_NO FROM AUCTIONS WHERE upper(ARTICLE_NAME) LIKE ?";
//CONCAT('%', ?, '%')";
echo "\ntest";
if ($numRecords = $con->prepare($countQuery)) {
    $numRecords->bind_param("s",  $brand);
    echo "\ntest bind";
    $numRecords->execute();
    echo "\ntest exec";
    $numRecords->store_result();
    $data = $con->query($countQuery) or die(print_r($con->error));
    $rowcount = $data->num_rows;
    $numRecords->free_result();
    $numRecords->close();
    echo "/ntest before rows";
    $rows = getRowsByArticleSearch("test", "Auctions", " ");
    $last = ceil($rowcount/$page_rows);
} else {
    print_r($con->error);
}
foreach ($rows as $row) {
    $pk = $row['ARTICLE_NO'];
    echo '<tr>' . "\n";
    echo '<td><a href="#" onclick="updateByPk(\'Layer2\', \'' . $pk . '\')">'.$row['USERNAME'].'</a></td>' . "\n";
    echo '<td><a href="#" onclick="updateByPk(\'Layer2\', \'' . $pk . '\')">'.$row['shortDate'].'</a></td>' . "\n";
    echo '<td><a href="#" onclick="deleterec(\'Layer2\', \'' . $pk . '\')">DELETE RECORD</a></td>' . "\n";
    echo '</tr>' . "\n";
}
function getRowsByArticleSearch($searchString, $table, $max) {
    $con = mysqli_connect("localhost", "blah", "blah", "blah");
    //global $con;
    $recordsQuery = "SELECT ARTICLE_NO, USERNAME, ACCESSSTARTS, ARTICLE_NAME, date_format(str_to_date(ACCESSSTARTS, '%d/%m/%Y %k:%i:%s'), '%d %m %Y' ) AS shortDate FROM $table WHERE upper(ARTICLE_NAME) LIKE '%?%' ORDER BY str_to_date(ACCESSSTARTS, '%d/%m/%Y %k:%i:%s')" . $max;
    if ($getRecords = $con->prepare($recordsQuery)) {
        $getRecords->bind_param("s", $searchString);
        $getRecords->execute();
        $getRecords->bind_result($ARTICLE_NO, $USERNAME, $ACCESSSTARTS, $ARTICLE_NAME, $shortDate);
        while ($getRecords->fetch()) {
            $result = $con->query($recordsQuery);
            $rows = array();
            while($row = $result->fetch_assoc()) {
                $rows[] = $row;
            }
            return $rows;
        }
    }
}

El error exacto es:

You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '?' at line 11

La línea 11 es la línea que define $ countQuery.

como puede ver, la marca se considera como " o " ;;

Por lo tanto, la declaración SQL debería ser

SELECT ARTICLE_NO FROM AUCTIONS WHERE upper(ARTICLE_NAME) LIKE %o%;

Que funciona bien cuando lo puse manualmente.

¿Fue útil?

Solución

mysqli_stmt :: bind_param solo puede vincular una variable específica, no una expresión. La variable suministrada se pasa a 'vincular' por referencia, y no por valor, lo que significa que el SQL subyacente obtiene el valor que tiene esa variable en el momento en que se ejecuta el comando, no cuando está vinculado.

Uso:

WHERE field LIKE CONCAT('%', ?, '%")

o hacer:

$brand = '%' . $brand . '%'

inmediatamente antes de que se ejecute el comando.

Lo que no puedes hacer es:

WHERE field LIKE '%?%

porque la variable enlazada ? debe corresponder a una sola cadena o valor numérico, no a una subcadena (o nombre de campo).

EDIT en este caso, su problema real parece estar mezclando declaraciones preparadas (como lo admite mysqli :: prepare y mysqli_stmt :: execute () ) con consultas antiguas (como se hizo con mysqli :: consulta () ). También debe solicitar el número de filas directamente desde el servidor de la base de datos, en lugar de extraer los datos y utilizar num_rows:

$countQuery = "SELECT COUNT(ARTICLE_NO) FROM AUCTIONS WHERE upper(ARTICLE_NAME) LIKE ?";
if ($numRecords = $con->prepare($countQuery)) {
    $numRecords->bind_param("s",  $brand);
    $numRecords->execute();
    $numRecords->bind_result($num_rows);
    $numRecords->fetch();
    $numRecords->free_result();
    $numRecords->close();
    $last = ceil($rowcount/$page_rows);
} else {
    print_r($con->error);
}

Otros consejos

El problema no está en la declaración preparada, sino en el método de "consulta" que no debería estar allí, ya que se utiliza para ejecutar " estándar " Declaraciones (no preparadas).

$data = $con->query($countQuery) or die(print_r($con->error));
$rowcount = $data->num_rows;

debería ser

$rowcount = $numRecords->num_rows;

en la función getRowsByArticleSearch, debe volver a eliminar la consulta y usar las variables pasadas a bind_result para el resultado:

  $getRecords->bind_result($ARTICLE_NO, $USERNAME, $ACCESSSTARTS, $ARTICLE_NAME, $shortDate);
  while ($getRecords->fetch()) {
    $pk = $ARTICLE_NO;
    echo '<tr>' . "\n";
    echo '<td><a href="#" onclick="updateByPk(\'Layer2\', \'' . $pk . '\')">'.$USERNAME.'</a></td>' . "\n";
    // etc...
  }

para obtener más información, consulte el manual de PHP de bind_result: http : //php.net/manual/en/mysqli-stmt.bind-result.php

Esta publicación en mysql.com parece sugerir que CONCAT () debería funcionar: http://forums.mysql.com/read.php? 98,111039,111060 # msg-111060

¿Has intentado usar parámetros con nombre?

Intentas llamar:

$numRecords->bind_param("s", "%".$brand."%");

Pero tu sql es:

$countQuery = "SELECT ARTICLE_NO FROM AUCTIONS WHERE upper(ARTICLE_NAME) LIKE ?";

¿No debería ser? (note el LIKE? s )

$countQuery = "SELECT ARTICLE_NO FROM AUCTIONS WHERE upper(ARTICLE_NAME) LIKE ?s";
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top