Ankündigung

Einklappen
Keine Ankündigung bisher.

Importieren einer Sql-Datei

Einklappen

Neue Werbung 2019

Einklappen
X
  • Filter
  • Zeit
  • Anzeigen
Alles löschen
neue Beiträge

  • MerlinderZauberer
    hat ein Thema erstellt Importieren einer Sql-Datei.

    Importieren einer Sql-Datei

    Hallo,

    ich habe eine TXT-Datei erstellt, in der sich MySQL-Befehlen befindet.

    Auf der MySQL-Shell-Ebene besteht die Möglichkeit, meineTXT-Datei mittels dem Befehl "source Dateiname" zu importieren. Funktioniert auch.

    Versuche das ganze als MySQL-Query abzusetzen, schlagen fehl. Fehlermeldungen gibt es keine.

    PHP-Code:
    <?php

    mysql_query
    ("SOURCE [i]Dateiname[/i]",dbhandler);

    ?>
    Gibt es ein SQL-Statment, mithilfe dessen ich eine solche Textdatei einlesen kann?

    Kann man Grundsätzlich alle Befehle auf der Shellebene auch in einem MySQL-Query auf PHP-Ebe ne nutzen?

    Zugriff auf Exec() habe ich nicht.

    Merlin der Zauberer

  • MerlinderZauberer
    antwortet
    Hallo Zergling,

    danke für Deinen Code.

    Ich habe ihn nicht ausprobiert, da ich zwischenzeitlich meine Klasse etwas anders gestaltet habe.

    Ich habe mich dazu entschlossen, jedes Query mit nur einem Befehl zu bestücken. Das ergibt für mich eine sinnvolle Fehleranalyse.
    Desweiteren werden alle folgenden Querys bei Fehlschlägen soweit Möglich ausgeführt.

    Die Klasse von mir funktioniert gut. Für 1300000 (Millionen!) Querys inklusive auslesen aus den Tabellen braucht mein Script 30 Minuten.

    Merlin der Zauberer

    Einen Kommentar schreiben:


  • Zergling-new
    antwortet
    Hallo,
    habe hier eine kleine Funktion geschrieben, vielleicht kannst du sie verwenden und Feedback über das korrekte zerlegen geben:
    PHP-Code:
    <?php
    function getQueriesFromFile($file)
    {
        
    // import file line by line
        // and filter (remove) those lines, beginning with an sql comment token
        
    $file array_filter(file('import.sql'),
                             
    create_function('$line',
                                             
    'return strpos(ltrim($line), "--") !== 0;'));
        
    // this is a list of SQL commands, which are allowed to follow a semicolon
        
    $keywords = array('ALTER''CREATE''DELETE''DROP''INSERT''REPLACE''SELECT''SET',
                          
    'TRUNCATE''UPDATE''USE');
        
    // create the regular expression
        
    $regexp sprintf('/\s*;\s*(?=(%s)\b)/s'implode('|'$keywords));
        
    // split there
        
    $splitter preg_split($regexpimplode("\r\n"$file));
        
    // remove trailing semicolon or whitespaces
        
    $splitter array_map(create_function('$line',
                                              
    'return preg_replace("/[\s;]*$/s", "", $line);'),
                              
    $splitter);
        
    // remove empty lines
        
    return array_filter($splittercreate_function('$line''return !empty($line);'));
    }
    ?>

    Einen Kommentar schreiben:


  • MerlinderZauberer
    antwortet
    Zitat von nikosch77
    Etwas abgeändert bekommst Du so die einzelnen Befehle in einem Array:

    PHP-Code:
    $sAll file_get_contents ('test.txt');
    $aQueries preg_split ('/;\s*[\n\r]+/' $sAll); 
    Ansonsten täte es auch ein
    PHP-Code:
    $sAll file_get_contents ('test.txt');
    $aQueries explode (";\r\n" $sAll); 
    Gesetzt den Fall, Du hältst Dich konsequent an das Muster.
    Du hast recht, mit meinen substr sieht es nicht besonders elegant aus. Ich habe allerdings das Problem, das z.B. in Feld meiner Datenbank das Delemiter vorkommen kann. Mit dem substr wollte ich das vermeiden. Tatsächlich muß ich aufgrund von Leerzeichen die letzten 3-4 Zeichen einer Zeile prüfen.

    Hier brauche ich letzendlich nur das Zeichen $ für Stringende nutzen, damit wäre mein substr erledigt, denke ich mal. Aus dem FF-Denke ich mal so:

    PHP-Code:
    preg_match("/\;(\r)*$/",$zeile);       # ungetestet 
    Die Lösung mit dem Array habe ich auch überlegt. Allerdings stoße ich hier aufgrund der Dateigröße und der großen Anzahl von Query´s an die Grenze des Verfügbaren Arbeitsspeicher (Hoster). Deswegen das Auslesen jeder Zeile.

    Zitat von nikosch77
    Was meinst Du mit bündeln? Z.B. Multi-Inserts?
    Das wäre der richtige Begriff gewesen Das meine ich!

    Zitat von phpdummi
    Ich dachte das hilft. Gefunden habe ich das Tutorial bei einer Suche nach "mysql dump php" unter den ersten 10 Ergebnissen, deshalb die blöde Anmerkung oben.
    Manchmal sucht man nicht mit den elementaren Dingen...
    Gesucht habe ich jedenfalls

    Danke für eure Antworten

    Merlin der Zauberer

    Einen Kommentar schreiben:


  • phpdummi
    antwortet
    Ich meinte dieses Tutorial:
    http://phpfriend.de/forum/ftopic32995.html

    Dort steht im Script sql_back.php:
    PHP-Code:
    <?php
    /**
    * [...]
    */

    // read file into database
    $mysql mysql_connect($mysql_hostname$mysql_username$mysql_password) or die("Could not connect to $mysql_hostname - ".mysql_error());
    mysql_select_db($mysql_database) or die("Could not select database $mysql_database - ".mysql_error());

    $dump file($filename) or die("Could not read file $filename");
    foreach (
    $dump as $data) {
      if (
    strlen($data) > 1mysql_query(substr($data0, -1)) or die("Could not exec $data - ".mysql_error());
    }

    /**
    * [...]
    */

    ?>
    Ich dachte das hilft. Gefunden habe ich das Tutorial bei einer Suche nach "mysql dump php" unter den ersten 10 Ergebnissen, deshalb die blöde Anmerkung oben.
    Tut mir leid

    Einen Kommentar schreiben:


  • nikosch
    antwortet
    Ist auf jeden Fall eine Variante. Die Kombination von preg_match () und substr () ist etwas doppelt gemoppelt. Je nach Ausgangsdatei wäre es vielleicht sinnvoll, zwischen ; und Zeilenende noch Leerzeichen zu erlauben.

    Etwas abgeändert bekommst Du so die einzelnen Befehle in einem Array:
    PHP-Code:
    $sAll file_get_contents ('test.txt');
    $aQueries preg_split ('/;\s*[\n\r]+/' $sAll); 
    Ansonsten täte es auch ein
    PHP-Code:
    $sAll file_get_contents ('test.txt');
    $aQueries explode (";\r\n" $sAll); 
    Gesetzt den Fall, Du hältst Dich konsequent an das Muster.

    Was meinst Du mit bündeln? Z.B. Multi-Inserts?

    Einen Kommentar schreiben:


  • MerlinderZauberer
    antwortet
    Hallo Ihr beiden,

    Zitat von phpdummi
    Äääh, dazu gibt in der Tutorial-Sektion einen schönen Beitrag
    Ich habe ja nun versucht, im Manuell und weiteren Quellen eine Lösung zu finden. Bin nur leider nicht fündig geworden. Habe das Problem anders gelöst. Damit umgehe ich unter anderem eine Excute des MySQL-Server.

    Ich lese die Zeilen einzeln aus und prüfe einen Demeliter am Ende der Zeile. Ist einer vorhanden, führe ich ein Query durch.

    Hier mal das Scriptschnipsel:

    PHP-Code:
    <?php
    $zeile       
    "";
    $dbquery  "";

    $datei gzopen(dateiname,"r");

    while(!
    FEOF($datei))
                            {
                            
    $zeilegzgets($datei);
                            
                            
    # Prüfen, ob Befehlsende erreicht
                            
    if (!preg_match("/\;/",(substr($zeile,strlen($zeile)-1,strlen($zeile)))))
                                {
                                
    # Zeile hinzufügen zum Query, Befehlsende nicht erreicht
                                
    $dbquery.= $zeile."\n";
                                }
                            else
                                {
                                
    # Zeile hinzufügen zum Query, Befehlsende erreicht
                                
    $dbquery.= $zeile;
                                
    $dbanfrage mysql_query($dbquery,$dbhandler);
                                
                                if (
    $dbanfrage == 0)
                                    {
                                    echo 
    "Folgendes Query ist fehlgeschlagen:";
                                    echo
    ".$dbquery."

    ";

                                    }
                                
    $dbquery = "";
                                }

    gzclose(
    $datei);
    Funktioniert einwandfrei.

    Jetzt eine weitere Frage! Ist es für die Perfomance nicht besser, mehrere SQL-Anfragen zu bündeln und an den MySQL-Server zu schicken?

    Manche Datenbanken erreichen mühelos 20-40 MByte.

    Merlin der Zauberer

    Einen Kommentar schreiben:


  • nikosch
    antwortet
    Ach ja? Ein Link wäre toll...

    Einen Kommentar schreiben:


  • phpdummi
    antwortet
    Äääh, dazu gibt in der Tutorial-Sektion einen schönen Beitrag

    Einen Kommentar schreiben:

Lädt...
X