Question

J'ai des problèmes pour exécuter une instruction préparée via mysqli.

Tout d’abord, j’obtenais des erreurs de synchronisation des commandes. Je stocke le résultat et ferme la connexion, et j'ai cessé de recevoir cette erreur, alors j'espère que le problème s'est arrêté.

Cependant, l'erreur dans mon erreur de syntaxe SQL, qui fonctionnait correctement alors que les commandes n'étaient pas synchronisées, est réapparue. Voici mon code actuel:

J'ai essayé de nombreuses approches différentes pour corriger cette erreur de syntaxe, à l'aide de l'utilisation de CONCAT, commentée lorsqu’elle a échoué, de l’attribution de% de signes à la variable avant la liaison, etc.

Tentative d'utilisation:

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

Résultat en une erreur de passer par référence.

<?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;
        }
    }
}

L'erreur exacte est la suivante:

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 ligne 11 est la ligne définissant $ countQuery.

comme vous pouvez le constater, la marque est définie comme "o";

L'instruction SQL doit donc être

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

Ce qui fonctionne bien quand je le mets manuellement.

Était-ce utile?

La solution

mysqli_stmt :: bind_param ne peut lier qu'une variable spécifique, mais pas une expression. La variable fournie est transmise à 'bind' par référence, et non par valeur, ce qui signifie que le code SQL sous-jacent obtient la valeur quelle que soit la valeur de cette variable au moment de l'exécution de la commande et non lorsqu'elle est liée.

Utiliser:

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

ou faire:

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

immédiatement avant l'exécution de la commande.

Ce que vous ne pouvez pas faire, c'est:

WHERE field LIKE '%?%

car la variable liée ? doit correspondre à une chaîne ou à une valeur numérique unique et non à une sous-chaîne (ou un nom de champ).

MODIFIER , dans ce cas, votre vrai problème semble être de mélanger des instructions préparées (comme le supporte mysqli :: prepare et mysqli_stmt :: execute () ) avec de vieilles requêtes simples (comme avec mysqli :: query () ). Vous devriez également simplement demander le nombre de lignes directement du serveur de base de données, plutôt que d'extraire les données et d'utiliser 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);
}

Autres conseils

Le problème ne se trouve pas dans l'instruction préparée, mais dans l'appel de la méthode 'query' qui ne devrait pas exister - car elle est utilisée pour exécuter "standard". (non préparé) déclarations.

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

devrait être

$rowcount = $numRecords->num_rows;

dans la fonction getRowsByArticleSearch, vous devez à nouveau supprimer la requête et utiliser les variables transmises à bind_result pour le résultat:

  $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...
  }

Pour plus d'informations, consultez le manuel PHP de bind_result: http : //php.net/manual/en/mysqli-stmt.bind-result.php

Ce billet sur mysql.com semble suggérer que CONCAT () devrait fonctionner: http://forums.mysql.com/read.php? 98,111039,111060 # msg-111060

Avez-vous essayé d'utiliser des paramètres nommés?

Vous essayez d'appeler:

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

Mais votre sql est:

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

Ne devrait-il pas en être ainsi? (notez les LIKE? s )

$countQuery = "SELECT ARTICLE_NO FROM AUCTIONS WHERE upper(ARTICLE_NAME) LIKE ?s";
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top