# MySQL Binary Search – Fehlerhafte Zeile automatisch finden ## Hintergrund Bei der Migration von Daten zwischen zwei Tabellen treten gelegentlich Fehler auf. Mit `LIMIT` und `OFFSET` lässt sich der fehlerhafte Bereich manuell eingrenzen – dieser Prozess kann jedoch durch einen Binary-Search-Ansatz vollständig automatisiert werden. --- ## Einfaches Skript (SELECT *) Für ein simples `SELECT *` ohne komplexe Query: ```bash #!/bin/bash # Konfiguration DB_USER="root" DB_PASS="password" DB_NAME="datenbank" SOURCE_TABLE="quelle" TARGET_TABLE="ziel" # Gesamtanzahl Zeilen ermitteln TOTAL=$(mysql -u"$DB_USER" -p"$DB_PASS" "$DB_NAME" -sNe \ "SELECT COUNT(*) FROM $SOURCE_TABLE;") echo "Gesamt Zeilen: $TOTAL" LOW=0 HIGH=$TOTAL while [ $((HIGH - LOW)) -gt 1 ]; do MID=$(( (LOW + HIGH) / 2 )) FETCH=$((MID - LOW)) echo "Teste OFFSET=$LOW LIMIT=$FETCH ..." ERROR=$(mysql -u"$DB_USER" -p"$DB_PASS" "$DB_NAME" 2>&1 < **Wichtig:** Ein `ORDER BY` ist zwingend erforderlich, damit die Zeilenreihenfolge zwischen den Aufrufen deterministisch bleibt. ```bash #!/bin/bash # Konfiguration DB_USER="root" DB_PASS="password" DB_NAME="datenbank" # Deine Source-Query OHNE LIMIT/OFFSET – als Subquery nutzbar SOURCE_QUERY="SELECT a.id, MAX(b.wert), a.name FROM quelle a JOIN andere b ON a.id = b.ref_id GROUP BY a.id, a.name ORDER BY a.id" TARGET_TABLE="ziel" # Gesamtanzahl Zeilen der Query ermitteln TOTAL=$(mysql -u"$DB_USER" -p"$DB_PASS" "$DB_NAME" -sNe \ "SELECT COUNT(*) FROM ($SOURCE_QUERY) AS _count_query;") echo "Gesamt Zeilen: $TOTAL" LOW=0 HIGH=$TOTAL while [ $((HIGH - LOW)) -gt 1 ]; do MID=$(( (LOW + HIGH) / 2 )) FETCH=$((MID - LOW)) echo "Teste OFFSET=$LOW LIMIT=$FETCH ..." ERROR=$(mysql -u"$DB_USER" -p"$DB_PASS" "$DB_NAME" 2>&1 <