Zur Navigation

SQL-Abfrage wird nach Umstellung auf PHP7 falsch interpretiert

1 AndiN

Hallo zusammen,
nach einem Update von PHP 5.2 auf PHP 7.0 scheint folgende SQL-Abfrage plötzlich anders zu funktionieren:
mysqli_query($sql,"UPDATE datenbank SET Position = Position+1 WHERE Position >= 4 AND Position < 8);

Unter PHP 5.2 passiert folgendes:
Setze bei allen Datensätzen bei welchen der Wert für Position >= 4 und < 8 ist auf den Wert für Position auf Position+1

Das hat bisher super funktioniert.
Nach der Umstellung auf PHP 7.0 reagiert die SQL-Abfrage offenbar wie folgt:

Setze die nächsten 4 SQL-Datensätze bei denen Position >= 4 und < 8 ist, alle auf Position = 8

Kann sich das jemand von euch erklären?

EDIT:
Ich habe es auch gerade direkt im phpMyAdmin getestet. Hier verhält es sich auch so falsch.

03.02.2017 22:48 | geändert: 03.02.2017 22:50

2 Jörg Kruse

Da fehlt ein " am Ende der Query - Copy & Paster Fehler?

Ich habe es auch gerade direkt im phpMyAdmin getestet. Hier verhält es sich auch so falsch.

phpMyAdmin läuft zwar auch auf PHP - aber die Query wird ja von MySQL ausgeführt. Gab es da auch ein Update?

POSITION ist ein Funktionsname in MySQL 5.7:

https://dev.mysql.com/doc/refman/5.7/en/string-functions.html#function_position

... maskiere den Namen mal mit Backspaces:

UPDATE datenbank SET `Position` = `Position`+1 WHERE `Position` >= 4 AND `Position` < 8

04.02.2017 10:14

3 AndiN

Ja, das fehlender Anführungszeichen war ein Copy&Paste-Fehler.

Das Einsetzen von Backspaces hat an der Fehlfunktion leider nichts geändert.
Bei der SQL-Version wurde mit der Änderung der PHP Version auf SQLi umgestellt. Könnte das das Problem verursachen?

06.02.2017 15:37

4 Jörg Kruse

mysqli übermittelt nur die Query - ausgeführt wird sie von dem Datenbankserver.

Auch über phpMyAdmin wird die korrigierte Query anders als gewünscht ausgeführt?

Edit:

oder meinst du mit SQLi die Datenbank SQLite?

06.02.2017 17:04 | geändert: 06.02.2017 17:07

5 AndiN

Auch per phpMyAdmin wird die korrigierte Query leider nicht wie gewünscht ausgeführt.

Mit SQLi meinte ich, dass wir im Zuge der Umstellung auf PHP7 nicht mehr MySQL sondern MySQLi benutzen. Also z. B. "mysqli_query" anstatt "mysql_query".

07.02.2017 13:53 | geändert: 07.02.2017 14:18

6 Jörg Kruse

Ich habe mal kurz getestet:

CREATE TABLE `test_position` (
  `id` int(10) UNSIGNED NOT NULL,
  `Position` int(10) UNSIGNED NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

INSERT INTO `test_position` (`id`, `Position`) VALUES
(1, 1),
(2, 2),
(3, 3),
(4, 4),
(5, 5),
(6, 6),
(7, 7),
(8, 8),
(9, 9),
(10, 10);

Folgende Query:

UPDATE test_position SET `Position` = `Position`+1 WHERE `Position` >= 4 AND `Position` < 8

... führt dazu, dass in den Datensätze 4 bis 8 erwartungsgemäß der Wert für `Position` um einen Zähler hochgezählt wird.

Die Query habe ich in phpMyAdmin 4.6.6 abgesetzt, PHP-Version 7.0.15-1;
als Datenbankserver läuft hier MariaDB 10.0.28 - wobei dieser weitgehend kompatibel zu MySQL sein sollte

Ist die gepostete Query denn soweit vollständig? wenn nein: verwendest du vielleicht sonst noch irgendwelche reservierten Wörter in der Abfrage?

Und wie ist das Datenfeld `Position` definiert? am besten du postest mal ein "CREATE TABLE"-Statement zum Anlegen der (leeren) Datenbanktabelle

07.02.2017 14:58

7 AndiN

Ich habe gerade festgestellt, dass das Script auf einer von der Datenbank-Struktur her völlig identischen Website korrekt funktioniert. Insofern kann es jetzt eigentlich nur noch an Sonderzeichen o. ä. in den Datenbank-Inhalten liegen.

Ich teste das jetzt mal.

07.02.2017 18:22

8 AndiN

Lösung:
Das Problem beruhte auf menschlichem Versagen ein paar Zeilen über dem geposteten Quelltext bei der Umstellung auf PHP7.

Ich glaube irgendwann wird da mal eine Flasche Wein fällig für dich!

08.02.2017 15:34

9 Jörg Kruse

Lass mich raten :) - eine Schleife wurde nicht richtig geschlossen? das würde nämlich erklären, warum die Positionen (nach mehreren Durchläufen) auf den Wert 8 gesetzt werden

Komisch allerdings, dass das Problem auch mit phpMyAdmin auftrat

08.02.2017 15:52 | geändert: 08.02.2017 15:52

10 AndiN

Nein, keine Schleife. Anbei das komplette Script.
Schau dir mal Zeile 5 genauer an. Ich sag nur "Copy/Paste" ! :-)

$old = $_REQUEST['idsort'];
$idakt1 = $_REQUEST['idakt'];
$new = $_REQUEST["position".$old];
if($new != $old){
	mysqli_query($sql,"mysqli_UPDATE ".$datenbank_aktiv." SET Position = 0 WHERE ID = ".$idakt1);
	if($old > $new){
		mysqli_query($sql,"UPDATE ".$datenbank_aktiv." SET Position = Position +1 WHERE Position >= ".$new." AND Position < ".$old);
		mysqli_query($sql,"UPDATE ".$datenbank_aktiv." SET Position = ".$new." WHERE ID = ".$idakt1);
	}
	else	{
		$connect = mysqli_query($sql,"SELECT ID FROM ".$datenbank_aktiv) or die(mysqli_error($sql));
		$entries = mysqli_num_rows($connect); 
		if($new > $entries){
			echo "<script>alert('Die Position '".$new."' ist nicht vorhanden. Das Thema wird daher auf Position '".$entries."' verschoben.');</script>";
			$new = $entries;
		}
		mysqli_query($sql,"UPDATE ".$datenbank_aktiv." SET Position = Position -1 WHERE Position > ".$old);
		mysqli_query($sql,"UPDATE ".$datenbank_aktiv." SET Position = Position +1 WHERE Position >= ".$new);
		mysqli_query($sql,"UPDATE ".$datenbank_aktiv." SET Position = $new WHERE ID = ".$idakt1);
	}
}

edit:
Dass es im phpMyAdmin falsch lief war vermutlich gar nicht so, sondern ich hatte vermutlich übersehen, dass die Einträge davor auch schon falsch waren.

08.02.2017 16:06 | geändert: 08.02.2017 16:08