简体   繁体   中英

Error when running SQL syntax

Upon running this script, I'm receiving this error:

Warning: mysqli_num_rows() expects parameter 1 to be mysqli_result, boolean given in ... On this line : if (mysqli_num_rows($result3) > 0) {

Any idea what's wrong?

if (isset($_POST['submit'])) 
    {
        $sql = "SHOW COLUMNS FROM Work";
        $result = mysqli_query($con,$sql);
         while($row = mysqli_fetch_array($result)){
                    $tempname = $row['Field'];
                    $sql2 = "UPDATE Work SET `".$row['Field']."`= '$_POST[$tempname]' WHERE ID='".$_GET["id"]."' AND Date='".$_GET["date"]."'";

                    $result2 = mysqli_query($con,$sql2);
                    if ($con->query($sql2) === TRUE) {
                    } else {
                        echo "Error: " . $sql2 . "<br>" . $con->error;
                    }
        }
         $sql3 = "SELECT * FROM Work WHERE ID='".$_GET["id"]."' AND (".$row['Field']." NOT LIKE '".$_POST[$tempname]."')";

The error:

Warning: mysqli_num_rows() expects parameter 1 to be mysqli_result, boolean given

is almost always because you've tried to execute a query and it's failed for some reason, but you've continued on blindly anyway.

Upon failure, mysqli_query will return false rather than a mysqli_result and, if you then attempt to use that boolean false value in something like mysqli_num_rows , that's exactly the error you'll see.

As a first point, you should always check the return value of functions that can fail, that's just good practice. Continuing blindly and hoping for the best is not really a way to produce robust code.


Having said that, you then have to move on to why the query has failed. A large proportion of SQL problems become obvious if you just print out the query before trying to execute it. It looks like you've eventually done this since one of your comments states that your query is:

SELECT * FROM Workhours WHERE AFNumber='AF1475' AND ( NOT LIKE '')

This is not a valid SQL statement, hence the problem. Now, despite the fact it appears to be using a different table name (an earlier edit of your question did have a matching table name), it corresponds closely to your $sql3 variable 1 :

$sql3 = "SELECT * FROM Work WHERE ID='".$_GET["id"]."' AND (".$row['Field']." NOT LIKE '".$_POST[$tempname]."')";

Hence it appears that neither $row['Field'] nor $_POST[$tempname] are actually set to anything.

That's where you need to concentrate your effort, to find out exactly why they aren't set.

For a start, it seems rather unwise to be using $row[anything] after the loop processing the rows has finished. It may well be that you need to move that code to within the loop to get it working but, without more information and context, that's really just conjecture (though educated conjecture).


1 If it's not the right query (I've just noticed it also uses ID rather than AFNumber ), then the problem lies elsewhere other than the code you've shown. However, the method used to find the problem will remain the same: find the problematic query, print it out before execution, then work out why it's malformed.

Error is sql statement,

You are using reserved word as column name, it should be enclosed with back tick as follows

`Date`

$sql2 = "UPDATE Workhours SET `".$row['Field']."`= '$_POST[$tempname]' WHERE AFNumber='".$_GET["af"]."' AND `Date`='".$_GET["date"]."'";

You are messing up with single quotes and double quotes and missing them in many places. Also, as I already pointed out in the comments, it is hard to debug by guessing. You should echo the mysql error you get when running the query. What you echo by now is that the after running the query you don't get an array of results: but this is caused by the query to have an issue. Many times it is just a matter of reading the error provided to understand what is going wrong. Finally: you can get this also because you don't have any error but you are just retrieving an empty set of results from the query (no record satisfy your query) Change this query to this:

$sql2 = "UPDATE Workhours SET `{$row['Field']}` = '{$_POST[$tempname]}' 
WHERE AFNumber='{$_GET['af']}' AND Date='{$_GET['date']}'";

For $sql3:

$sql3 = "SELECT * FROM Workhours WHERE AFNumber='{$_GET['af']}' 
AND (`{$row['Field']}` NOT LIKE '%{$_POST[$tempname]}%')";

NOTE I am not getting in the details of the many issues your actual code has: first of all that is open to SQL Injections as many has already pointed out: take a bit of time to see what prepared statements are. Also consider moving to PDO instead of mysqli.

your coding technique needs much improvement,

and the problem is clearly in Get and Post .

In this particular case , i would recommend , using $_REQUEST in place of all post and get. so your query gets all params , and your code goes perfect.

你可以试试这条线:

while($row = $result->fetch_array(MYSQLI_ASSOC)){

What I can see simply reviewing the lastly edited code is this:

if (isset($_POST['submit'])) 
    {
        $sql = "SHOW COLUMNS FROM Work";

        // ====> This new var is here to allow us retrieving
        // the last row after the while loop, because the
        // "$row" var will be equal to false at the end.
        $lastRow = null;

        $result = mysqli_query($con,$sql);
        while($row = mysqli_fetch_array($result)){
            $tempname = $row['Field'];
            $sql2 = "UPDATE Work SET `".$row['Field']."`= '$_POST[$tempname]' WHERE ID='".$_GET["id"]."' AND Date='".$_GET["date"]."'";
// ====> The previous line should be replaced with this:
            $sql2 = 'UPDATE Work SET `'.$row['Field'].'`= "'.htmlspecialchars($_POST[$tempname], ENT_QUOTES).'" WHERE ID="'.((int) $_GET["id"]).'" AND Date="'.htmlspecialchars($_GET["date"], ENT_QUOTES).'"';


            $result2 = mysqli_query($con,$sql2);
            if ($con->query($sql2) === TRUE) {
                $lastRow = $row;
            } else {
                echo "Error: " . $sql2 . "<br>" . $con->error;
            }
        }
         $sql3 = "SELECT * FROM Work WHERE ID='".$_GET["id"]."' AND (".$row['Field']." NOT LIKE '".$_POST[$tempname]."')";
// ====> The previous line should be replaced with this:
        if (isset($_POST[$tempname]) && !empty($_POST[$tempname]) && $lastRow) {
            $sql3 = 'SELECT * FROM Work WHERE ID="'.((int)$_GET['id']).'" AND (`'.$lastRow['Field'].'` NOT LIKE "'.htmlspecialchars($_POST[$tempname], ENT_QUOTES).'")';
        } else {
            // Show some error here
        }

Mostly, I refactored a little your SQL queries to: * Standardize the single/double quotes * Use "htmlspecialchars" to avoid some injections with the POST and GET variables.

This is for the seen code.

Now, for the rest, you lack many things in your coding practices.

  1. First, you need to add a LOT of security passes to your code. Here, you are retrieving the $_GET['id'] query parameter and some $_POST vars. You MUST validate them to avoid any kind of SQL injection.
  2. This workflow seems wrong: you are updating fields that are listed in POST datas. Without my changes, anyone can make a request to your website like this: /?id=5&date=anyDate , and in POST datas can send this: Field="" WHERE 1 -- . Classic injection, will break your app probably.
  3. You should reconsider the use of mysqli and use PDO instead, even if both can handle prepared. It's just an opinion.
  4. You should use standards in your way of coding, change var names for more "explicative" vars, etc. Changing $sql , $sql2 and $sql3 for $sqlColumns , $sqlUpdate and $sqlLastCheck would be more verbose, for example. Also, you should use one unique standard for quoting elements in your strings. Using single quotes for every PHP string and double quotes for SQL queries is one very common practice, and I recommend you to switch to this method.
  5. You should use some smart IDE like SublimeText, PhpStorm or any other IDE that suits to PHP coding. Most powerful ones like PhpStorm will inform you of many errors even before executing your code. Other like SublimeText will simply break syntax coloring when you make some errors like wrong quotes for example.

Hope it helps.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM