Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
1.1k views
in Technique[技术] by (71.8m points)

php - SQL like statement problems

I am having problems executing a prepared statement via mysqli.

First I was getting Command out of sync errors. I am storing the result and closing the connection, and I have stopped getting this error, so hopefully the problem has stopped.

However, the error in my sql syntax error, which was working fine while the commands were not in sync, has reappeared. Here is my current code:

I have tried many different approaches to correct this snytax error, from Using CONCAT, which is commented out as it failed, from assigning % signs to the variable before binding etc..nothing works.

Attempting to use:

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

Results in an error to pass by reference.

<?php
$con = mysqli_connect("localhost", "blah", "blah", "blah");
if (!$con) {
    echo "Can't connect to MySQL Server. Errorcode: %s
". mysqli_connect_error();
    exit;
}
$con->query("SET NAMES 'utf8'");
$brand = "o";
$brand = "% ".$brand." %";
echo "
".$brand;
$countQuery = "SELECT ARTICLE_NO FROM AUCTIONS WHERE upper(ARTICLE_NAME) LIKE ?";
//CONCAT('%', ?, '%')";
echo "
test";
if ($numRecords = $con->prepare($countQuery)) {
    $numRecords->bind_param("s",  $brand);
    echo "
test bind";
    $numRecords->execute();
    echo "
test 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>' . "
";
    echo '<td><a href="#" onclick="updateByPk('Layer2', '' . $pk . '')">'.$row['USERNAME'].'</a></td>' . "
";
    echo '<td><a href="#" onclick="updateByPk('Layer2', '' . $pk . '')">'.$row['shortDate'].'</a></td>' . "
";
    echo '<td><a href="#" onclick="deleterec('Layer2', '' . $pk . '')">DELETE RECORD</a></td>' . "
";
    echo '</tr>' . "
";
}
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;
        }
    }
}

The exact error is:

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

Line 11 is the line defining $countQuery.

as you can see, brand is assined as "o";

So the SQL statement should be

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

Which works fine when I put it in manually.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

mysqli_stmt::bind_param can only bind a specific variable, not an expression. The supplied variable is passed to 'bind' by reference, and not by value, meaning that the underlying SQL gets whatever value that variable has at the time the command is executed, not when it's bound.

Use:

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

or do:

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

immediately before the command is executed.

What you can't do is:

WHERE field LIKE '%?%

because the ? bound variable must correspond to a single string or numeric value, not to a substring (or field name).

EDIT in this case, your real problem appears to be mixing up prepared statements (as supported by mysqli::prepare and mysqli_stmt::execute()) with plain old queries (as done with mysqli::query()). You should also just ask for the number of rows directly from the DB server, rather than pull the data and use 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);
}

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...