Statistik |
Beiträge: 144.530 (Täglich: 19,19 )
Themen: 16.700
Mitglieder: 13.209
Neuestes Mitglied: zitronentee.
Ausl. d. letzten Minute: 360%
Ausl. d. letzten 5 Minuten: 394%
Ausl. d. letzten 15 Minuten: 362%
Aktulle Uhrzeit: 11:49
Freier Webspace: 4.02 TB
PHP-Version: 7.4.33
|
|
|
|
|
Massenbearbeitung Themen fehler |
|
Massenbearbeitung Themen fehler |
|
Hallo,
Wenn ich im acp massenbearbeitung Themen wähle und dann bestimmte bestimmte ausgewählte Foren löschen möchte, erhalte ich diese Fehlermeldung.
SQL-DATABASE ERROR
Database error in WoltLab Burning Board (2.3.6): Invalid SQL: UPDATE bb1_stats SET threadcount=threadcount-20, postcount=postcount-46
mysql error: BIGINT UNSIGNED value is out of range in '(`d022eda1`.`bb1_stats`.`threadcount` - 20)'
mysql error number: 1690
mysql version: 5.7.28-nmm1-log
php version: 7.4.2
Date: 30.04.2020 @ 14:42
Script: /acp/threads.php
Referer: /acp/threads.php?action=threads_mass_edi...nuitemgroupid=3
Vielen Dank im voraus.
|
|
30.04.2020 14:48 |
|
|
Viktor
Administrator
Zeige Viktor auf Karte
Dabei seit: 15.08.2003
Beiträge: 31.570
363 Filebase-Einträge
Alter: 66 Jahre
Herkunft: NRW wBB-Version: wBB2.3 PHP-Version: 7.4.33 MySQL-Version: 10.5.19-MariaDB Wo bist du gehostet?: eigener Server
Bewertung:
Level: 71 [?]
Erfahrungspunkte: 237.745.141
Nächster Level: 266.777.854
|
|
|
30.04.2020 21:09 |
|
|
|
Danke Viktor aber leider kommt jetzt dieser Fehler
Die gesuchte stelle ist 2mal drin. Hatte beide geändert.
php: |
1:
2:
3:
4:
5:
6:
7:
8:
9:
|
SQL-DATABASE ERROR
Database error in WoltLab Burning Board (2.3.6): Invalid SQL: UPDATE bb1_stats SET threadcount = ( CAST( threadcount AS SIGNED ) - 20, postcount = ( CAST( postcount AS SIGNED ) - 46
mysql error: 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 1
mysql error number: 1064
mysql version: 5.7.28-nmm1-log
php version: 7.4.2
Date: 30.04.2020 @ 22:14
Script: /acp/threads.php |
|
|
|
30.04.2020 22:23 |
|
|
|
Vielen dank Viktor fehler ist weg.
|
|
30.04.2020 22:44 |
|
|
|
Hallo,
Da mich Stine vor ca. 4 Wochen deshalb angeschrieben hat, die Änderung in die Anleitung zu übernehmen, und ich die Nachricht erst heute gelesen habe, daher Antworte ich mal hier:
Das Problem entsteht durch die Operation an sich.
Ein "signed" Bigint hat einen Bereich von -9223372036854775808 bis 9223372036854775807.
Ein "unsigned" Bigint hat einen Bereich von 0 bis 18446744073709551615.
Soweit so gut.
In unserem MySQL-Statement haben wir nun einen "unsigned" Minuenden(threadcount) und je nach Fall einen "unsigned" oder "signed" Subtrahenden($threadcount).
Beispielsweise werden folgende Varianten standardmäßig NICHT gleich behandelt:
php: |
1:
2:
3:
|
1. threadcount - ".intval($threadcount)."
2. threadcount + (-".intval($threadcount).")
3. threadcount + -".intval($threadcount)." |
|
Im ersten Fall handelt es sich um einen Subtrahend der im "unsigned" Bereich ist.
In den beiden anderen Fällen ist der Subtrahend immer im "signed" Bereich, da implizit ein Cast auf den Subtrahenden durchgeführt wird.
Unterschreitet der Subtrahend den "signed"-Bereich wird in diesen Fällen die gesamte Operation, unabhängig davon, ob der Minuend nun "signed" oder "unsigned" ist, auf den "signed" Bereich gecastet.
Bewegt sich der "Subtrahend" aber weiterhin im "signed" Bereich hängt es vom Minunend ab, ob nun das Endergebnis auf den "signed" Bereich gecastet wird, oder weiterhin im "unsigned" Bereich liegen muss. Letzteres würde weiterhin einen Fehler erzeugen.
Überschreitet der Subtrahend in Fall 1 den "unsigned" Bereich (>18446744073709551615) wird ebenfalls das gesamte Ergebnis auf den "signed" Bereich gecastet.
Castet man nur den Minuenden, muss sich sowohl der Subtrahend im "signed" Bereich bewegen, als auch das Endergebnis.
Multipliziert man eine der Komponenten mit einem "float", beispielweise "1.0", kommt ebenfalls ein impliziter Cast zur Anwendung und sorgt dafür, dass das Endergebnis auf den "signed" Bereich gecastet wird.
Das ganze Verhalten lässt sich auch auf eine Addition umlegen.
Das "unsigned" Problem lässt sich mit dem SQL-Modus "NO_UNSIGNED_SUBTRACTION" beheben, denn dadurch wird standardmäßig die gesamte Operation in den "signed" Bereich gecastet und wird niemals einen Overflow haben.
Sofern nun kein "Strict"-Modus aktiviert ist, wird aufgrund der Spalteneigenschaften ein falscher negativer Wert einfach auf "0" gesetzt und ein positiver Wert liegt ohnehin im "unsigned" Bereich, da er "9223372036854775807" nicht überschreiten kann.
Ist jedoch der "Strict"-Modus aktiv, erhält man für einen negativen Wert weiterhin eine Fehlermeldung.
Dadurch ist sowohl ein impliziter Cast, als auch ein expliziter Cast, wie hier im Thema vorgeschlagen, denkbar ungeeignet.
Eine "bessere allgemeinere Lösung" führt über den Weg, dass man die Spalte korrekt ausliest und die Subtraktion dementsprechend korrekt durchführt.
Das "Auslesen" kann man sich jedoch dank MySQL doch etwas sparen, wenn man "CASE", "LEAST" oder Ähnliches verwendet:
php: |
1:
|
threadcount = CASE WHEN threadcount >= ".intval($threadcount)." THEN threadcount - ".intval($threadcount)." ELSE 0 END |
|
oder
php: |
1:
|
threadcount = threadcount - LEAST(threadcount, ".intval($threadcount).") |
|
Dadurch wird sichergestellt, dass der Wert bei der Subtraktion immer im erlaubten Bereich ist.
Unabhängig von "NO_UNSIGNED_SUBTRACTION" und dem "Strict"-Modus.
Mit freundlichen Grüßen,
Schrimm
__________________
|
|
18.11.2020 20:27 |
|
|
|
|
|
|