0

I have a MySQL view created using INNER JOIN of two tables. It is matching an ID number from the first table to the same ID in the second table in order to access more data.

CREATE OR REPLACE VIEW vy_enheterILager
AS
(
    SELECT enheter.enhID, enheter.produktID, batcher.inDatum, enheter.utDatum
    FROM enheter
    INNER JOIN batcher ON enheter.batchID = batcher.batchID
    WHERE enheter.utDatum IS NULL
)

I would like to update the utDatum column with a specific date on the first two rows of the view, ordered by the inDatum column.

This works in phpMyAdmin:

UPDATE vy_enheterILager
SET utDatum = '2018-05-06'
WHERE produktID = 3
ORDER BY inDatum
LIMIT 2

However, when trying to do it from PHP using a prepared statement, it does not work.

$sql = "UPDATE vy_enheterILager SET utDatum = ? WHERE produktID = ? ORDER BY inDatum LIMIT ?";
if($stmt = $mysqli->prepare($sql)){
    // Bind variables to the prepared statement as parameters
    $stmt->bind_param("sii", $param_utLevDatum, $param_utLevProdukt, $param_utLevAntal);

    // Set parameters
    $param_utLevDatum = $utLevDatum;
    $param_utLevProdukt = $utLevProdukt;
    $param_utLevAntal = $utLevAntal;

    // Attempt to execute the prepared statement
    if($stmt->execute()){
        // Records created successfully
        header("location: lager.php");
        exit();
    } else{
        printf("Error: %s.\n", $stmt->error);
    }
}

I get the following error:

Incorrect usage of UPDATE and ORDER BY.

Why does it work in phpMyAdmin and not from my PHP script? Thank you in advance.

EDIT: I believe this is a new question. I have seen the documentation of UPDATE mentioning this:

"For the multiple-table syntax, UPDATE updates rows in each table named in table_references that satisfy the conditions. In this case, ORDER BY and LIMIT cannot be used."

However, if what I am trying to do is not supported, how come it works from phpMyAdmin and not from PHP? It shouldn't be working at all, then? It's the same server!

lbs129
  • 1
  • 2
  • set your limit to a int not ? – Jonny May 06 '18 at 16:24
  • see also [`Incorrect usage of UPDATE and LIMIT` - https://stackoverflow.com/questions/29364389/incorrect-usage-of-update-and-limit](https://stackoverflow.com/questions/29364389/incorrect-usage-of-update-and-limit) – Sean May 06 '18 at 16:27
  • @Jonny Yes, it is an INT. – lbs129 May 06 '18 at 16:31
  • @Sean: Please see my edit of the question. – lbs129 May 06 '18 at 16:36
  • Why do you have LIMIT? and not LIMIT 2 or something – Jonny May 06 '18 at 16:48
  • @Jonny What do you mean? In the PHP code I use a prepared statement where the question mark represents the parameter being inserted, for example 2. – lbs129 May 06 '18 at 18:15
  • This is not a duplicate of the marked question. Why do moderators insist on closing questions as "duplicate" without actually reading them? It's slack, uncaring and unhelpful. Having said that, the first comment (jonny) is your answer: you can't replace "limit" with parameterized values; user ....inDatum LIMIT " . (int)$param_utLevAntal; instead. – Robbie May 07 '18 at 06:55
  • @mickmackusa I care about the order, because I only want to update the first x rows matching my WHERE clause. In order to update the correct rows, they need to be ordered. – lbs129 May 07 '18 at 12:37
  • @Robbie Thank you! Is it simply not possible to parametrize the INT following LIMIT? I didn't get this from what Jonny said, since $param_utLevAntal was already an INT. – lbs129 May 07 '18 at 12:44
  • @lbs129 That is correct. For simplicity (although it's more complex than this), consider that the ? is replaced with a quotation mark, the value and a quotation mark. So you have 'LIMIT "2"' which is not valid. Same for table names and field names. You can, however, wrap integer field values in quotes.... – Robbie May 08 '18 at 06:22
  • @Robbie Thanks, but I've parameterized the INT following LIMIT in another query, and it worked beautifully. Very strange. – lbs129 May 09 '18 at 17:30
  • @lbs129 - Strange indeed but now you know - don't do it again as it's not doing what you think. It's really simple to "make safe" by casting as an int, so just do that. – Robbie May 09 '18 at 21:55

0 Answers0