Stefan: MySQL Abfrage in Batchdatei verarbeiten

Hi, ich finde im Netz einfach kein Beispiel, wie man in einer Batchdatei eine Datenbankabfrage ähnlich wie in php verarbeitet. Die Abfrage selber ist hierbei nicht das Problem, aber das verarbeiten der Ergebnismenge.

Gibt es dazu irgendwo ein Tutorial oder kann mir das jemand erklären?

Konkret möchte ich ein paar Daten in eine Textdatei schreiben.

$handle = fopen("logfile.txt","a+");

$select = "SELECT
  Name,
  Email,
  Mobil,
  Fax,
  Tel
FROM table 
WHERE ID=$ID";
$result = mysqli_query($con,$select);
if(!$result) {
    //Error
}

if (mysqli_num_rows($result) > 0) {
    while($row = mysqli_fetch_assoc($result)) {
        if($row['Name'] != "" && $row['Name'] != "Heinz") {
            fwrite($handle,"Name: ".$row['Name']."\r\n");
        }
        if($row['Email'] != "") {
            fwrite($handle,"Mail: ".$row['Email']."\r\n");
        }
        if($row['Tel'] != "") {
            fwrite($handle,"Telefon: ".$row['Tel']."\r\n");
        }
        fwrite($handle,"\r\n");
    }
}

fclose($handle);

In php kein Akt, aber ich krieg nicht raus wie man das in einer Batch genauso wie im Beispiel machen kann.

Die Abfrage selber abschicken und das Ergebnis in eine Datei speichern, schaffe ich. Aber nicht, erstmal mit dem Ergebnis zu arbeiten. So würde also zb auch Heinz eingetragen. Oder eine leere Emailadresse. Oder andere Sachen, die hier jetzt nicht aufgeführt sind. Ich würde gerne das Ergebnis nochmal bearbeiten.

Stefan

  1. Hi,

    ich finde im Netz einfach kein Beispiel, wie man in einer Batchdatei eine Datenbankabfrage ähnlich wie in php verarbeitet.

    was spricht dagegen, php dazu zu benutzen? Das kann man ja auch auf der Kommandozeile ausführen ...

    cu,
    Andreas a/k/a MudGuard

    1. Hallo Andreas, meine Befürchtung ist, dass das PHP Skript aufgrund der datenfülle irgendwann abbrechen wird. Wie ist das eigentlich, wenn sich so ein Skript beispielsweise ein paar tausendmal selber aufruft? Machen die Provider das mit oder gibt es da Begrenzungen?

      Jedenfalls ist das der Grund, warum ich das über einen shellscript machen wollte.

      Stefan

      1. Hallo Stefan,

        meine Befürchtung ist, dass das PHP Skript aufgrund der datenfülle irgendwann abbrechen wird.

        ein PHP-Script, das von der Kommandozeile aufgerufen wird, hat kein Zeitlimit. Das gibt's nur, wenn es im Webserver-Kontext läuft. Der einzig limitierende Faktor ist dann wohl der Arbeitsspeicher.

        Wie ist das eigentlich, wenn sich so ein Skript beispielsweise ein paar tausendmal selber aufruft?

        Das wäre ungünstig. Aber wieso sollte das der Fall sein? in deinem PHP-Beispielscript kann ich weder eine interne, noch eine externe Rekursion erkennen (intern heißt, eine Funktion innerhalb des Scripts ruft sich selbst wieder auf; extern heißt, das ganze Script ruft sich selbst als Kindprozess nochmal auf). Nur eine while-Schleife, die mehr oder weniger oft durchlaufen würde. Das wäre aber ein streng sequentieller Ablauf.

        Machen die Provider das mit oder gibt es da Begrenzungen?

        Ah, du redest vom Hoster da draußen im Web? Dürftest du denn da überhaupt einfach so Batchdateien ausführen? Hast du einen Shell-Zugang?

        Jedenfalls ist das der Grund, warum ich das über einen shellscript machen wollte.

        Aber ob direkt in der bash oder mit PHP: Wenn eine große Datenmenge anfällt, ist das in beiden Fällen so. Wenn also Speicher der begrenzende Faktor ist, wird dich das in beiden Fällen treffen.

        Einen schönen Tag noch
         Martin

        --
        Wer andern eine Bratwurst brät,
        braucht wohl ein Bratwurstbratgerät.
        1. Hallo Martin,

          ja, einen Shell Zugang habe ich, ich könnte das Skript also ausführen.

          Die ganzen kindprozesse habe ich natürlich in meinem Beispiel weggelassen, ich dachte, dass ich die analog zu diesem Beispiel einbauen könnte.

          Stefan

  2. Einführend:

    Die Shell (welche denn?) kann man zwar für Skripte benutzen, diese kommt aber schnell an Grenzen, sie war nie als universelle Programmiersprache gedacht und wird wohl das Eine oder Andere nicht oder nicht effektiv können. Es gibt ja nicht grundlos so viele Programmiersprachen…

    In php kein Akt, aber ich krieg nicht raus wie man das in einer Batch genauso wie im Beispiel machen kann.

    Klar. Wenn PHP auch als CLI zur Verfügung steht (Du es via ssh starten kannst), dann führe mal

    ~$ which php
    

    aus.

    Das Ergebnis sieht etwa so aus:

    /usr/bin/php
    

    Im nächsten Schritt notierst Du das als „Shebang“ in der ERSTEN (sic: ersten!) Zeile des Skriptes:

    #!/usr/bin/php
    

    Achte auf das Ausrufezeichen und darauf, dass Dein Editor keine Unicode-BOM schreibt. (Meist unter „Kodierung“ einzustellen, fast nur bei Windows-Editoren ein „Problem“) Danach vergibst Du Dir selbst das Recht, das Skript auszuführen:

    chmod 700 Skript.php
    

    Starten kannst Du es dann mit

    ~$ ./Skript.php
    

    oder mit

    ~$ /pfad/zu/Skript.php
    

    Achte darauf, dass es nicht via Webserver abrufbar ist, denn es stehen ja Benutzername und Passwort für die Datenbank drin.

    Eine zusätzliche Bremse kannst Du wie folgt einbauen:

    #!/usr/bin/php
    
    if ( ! empty( $_SERVER['DOCUMENT_ROOT'] ) ) {
        exit;
    }
    

    Das sorgt dafür, dass das Skript stumpf abbricht, wenn es via Webserver ausgeführt wird, verhindert aber womöglich nicht, dass das Skript im Quelltext abgerufen wird. Lege es außerhalb des DOCUMENT_ROOT ab. Und vergib KEINE andere Endung!

    HINT: Die Variable $argv enthält im Falle eines CLI- Aufrufs ein Array mit dem Skriptaufruf selbst und der womöglich an das Skript übergebenen Argumente.

    Bei einem Aufruf mit

    ~$ ./Skript.php foo bar
    

    also

    $argv[0] → './Skript.php'
    $argv[1] → 'foo'
    $argv[2] → 'bar'
    

    Das gezeigte Skript sieht nicht so aus, als müsstest Du Dir Sorgen wegen des Speichers machen.

    1. Hallo Raketenwilli,

      ich habe das genau nach Deiner Anleitung gemacht und es funktioniert tatsächlich wunderbar.

      Deine Sicherheitstipps muß ich noch umsetzen, ich wollte zunächst sehen, ob ich das Script überhaupt über Konsole zum arbeiten bekomme und ob es nicht abbricht.

      Aber auch hier hattest Du und Deine Vorredner recht, im längsten Fall ist das Script nur ungefähr 5 Minuten unterwegs.

      Danke an alle für Eure Hilfe,

      Stefan

    2. Eine zusätzliche Bremse kannst Du wie folgt einbauen:

      #!/usr/bin/php
      
      if ( ! empty( $_SERVER['DOCUMENT_ROOT'] ) ) {
          exit;
      }
      

      Hm. Ich mach auch Fehler ...

      Da fehlt das <?php - sonst gibt PHP das Skript nur aus.

      #!/usr/bin/php
      <?php 
      if ( ! empty( $_SERVER['DOCUMENT_ROOT'] ) ) {
          exit;
      }
      

      Ich hab nach einer Option geschaut, mit der man die „PHP-Tags“ weglassen kann aber php -r funktioniert nur wenn man den Code als Einzeiler direkt dahinter notiert. Dabei hab ich was anderes gefunden.

      man 1 php in meinem Ubuntu liefert eine veraltete Information:

      TIPS You can use a shebang line to automatically invoke php from scripts. Only the CLI version of PHP will ignore such a first line as shown below:

      #!/bin/php
      <?php
      // your script
      ?>
      

      Der Pfad zu PHP mag unter Ubuntu gerade noch funktionieren, aber den Ordner /bin haben andere Distributionen schon nicht mehr (und PHP bzw. hat da auch nie wirklich hinein gehört). Unter Ubuntu 22.04 ist der ehemalige Ordner /binnur noch ein Link zu /usr/bin. Die obige Angabe (im für das brandaktuelle PHP 8.2 gelieferten Linux-Manual!) ist also aus Linux-Sicht „deprecated“.

      Aber wenn man in den (die) Ordner hineinsieht, dann findet man auf meinem System folgende Verweisungen durch Links heraus:

      • /usr/bin/php → /etc/alternatives/php → /usr/bin/php8.2

      Man kann in der Shebang also dem Muster in der obigen Zeile die Verwendung einer bestimmten PHP-Version erzwingen, die muss halt nur parallel installiert sein.