Recursively MySQL Query

3 Cevap php

Nasıl özyinelemeli MySQL sorguları uygulayabilirsiniz. Ben bunun için bakmak çalışıyorum ama kaynakların çok yararlı değildir.

Benzer mantığını uygulamak için çalışıyoruz.

public function initiateInserts()
{
    //Open Large CSV File(min 100K rows) for parsing.
    $this->fin = fopen($file,'r') or die('Cannot open file');

    //Parsing Large CSV file to get data and initiate insertion into schema.
    $query = "";
    while (($data=fgetcsv($this->fin,5000,";"))!==FALSE)
    {
        $query = $query + "INSERT INTO dt_table (id, code, connectid, connectcode) 
                 VALUES (" + $data[0] + ", " + $data[1] + ", " + $data[2] + ", " + $data[3] + ")";
    }
     $stmt = $this->prepare($query);
     // Execute the statement
     $stmt->execute();
     $this->checkForErrors($stmt);
}

@ Yazar: Numenor

Hata iletisi: 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 '0' at line 1

This Approach bir MySQL özyinelemeli sorgu yaklaşım aramak için ilham verdi.

Burada önce kullanıyordum Yaklaşım:

Current Code:

public function initiateInserts()
{
    //Open Large CSV File(min 100K rows) for parsing.
    $this->fin = fopen($file,'r') or die('Cannot open file');

    //Parsing Large CSV file to get data and initiate insertion into schema.
    while (($data=fgetcsv($this->fin,5000,";"))!==FALSE)
    {
        $query = "INSERT INTO dt_table (id, code, connectid, connectcode) 
                 VALUES (:id, :code, :connectid, :connectcode)";

        $stmt = $this->prepare($query);
        // Then, for each line : bind the parameters
        $stmt->bindValue(':id', $data[0], PDO::PARAM_INT);
        $stmt->bindValue(':code', $data[1], PDO::PARAM_INT);
        $stmt->bindValue(':connectid', $data[2], PDO::PARAM_INT);
        $stmt->bindValue(':connectcode', $data[3], PDO::PARAM_INT);

        // Execute the statement
        $stmt->execute();
        $this->checkForErrors($stmt);
    }
}

Updated Code

public function initiateInserts()
{
    //Open Large CSV File(min 100K rows) for parsing.
    $this->fin = fopen($file,'r') or die('Cannot open file');

    //Prepare insertion query to insert data into schema.
    $query = "INSERT INTO dt_table (id, code, connectid, connectcode) 
                 VALUES (:id, :code, :connectid, :connectcode)";

    $stmt = $this->prepare($query);
    // Then, for each line : bind the parameters
    $stmt->bindValue(':id', $data[0], PDO::PARAM_INT);
    $stmt->bindValue(':code', $data[1], PDO::PARAM_INT);
    $stmt->bindValue(':connectid', $data[2], PDO::PARAM_INT);
    $stmt->bindValue(':connectcode', $data[3], PDO::PARAM_INT);

  //Loop through CSV file and execute inserts prepared, but this is not working
  //and there are not data being populated into database. 
   while (($data=fgetcsv($this->fin,5000,";"))!==FALSE)
        {
            // Execute the statement
             list($id, $code, $connid, $conncode)=$data;

            $stmt->execute();
            $this->checkForErrors($stmt);
        }
    }

Bu oldu my Main Question Ben önerileri arıyorum hangi için!

3 Cevap

  • recursive hiçbir şey bu kod parçasında var.
  • Yanlış Operatör dizeleri bitiştirmek için kullanılır, . (dot) değil + bulunuyor
  • Sen mysqli::multi_query() tek bir işlev çağrısı ile birden fazla deyimini yürütmek için ve ifadeler (varsayılan bir noktalı virgül ile) bir ayırıcı karakteri ile ayrılmış olması gerekir gibi bir şey kullanmak zorunda
  • Zaten hazırlamak () ve yürütmek kullanıyorsanız bu yana () neden sadece bir parametrelenmişse hazır deyim yapmaz ve daha sonra döngünün her tekrarında değerler atamak ve deyim yürütmek? ($ Bu ve $ this-> hazırlamak gelmez ne tür bir nesnenin () return tam olarak nedir?)
  • düzenlemek söyliyim: $this->prepare() sınıf bir veritabanı sınıfını genişletir olduğunu gösterir. Ve aynı zamanda bir dosya tanıtıcı $this->fin tutar. Bu belli bir code smell vardır. Benim guess olduğunu sınıf uses/has veritabanı / DataSink nesne ve bir dosya / veri kaynağı değil, is Bir veritabanı + readfile sınıf. Sadece bir sınıf uzatmak eğer türetilen sınıf is şeydir.

edit: basit bir örnek

class Foo {
  protected $pdo;
  public function __construct(PDO $pdo) {
    $this->pdo = $pdo;
  }

  public function initiateInserts($file)
  {
    $query = '
      INSERT INTO
        dt_table_tmp
        (id, code, connectid, connectcode)
      VALUES
        (:id, :code, :connid, :conncode)
    ';
    $stmt = $this->pdo->prepare($query);
    $stmt->bindParam(':id', $id);
    $stmt->bindParam(':code', $code);
    $stmt->bindParam(':connid', $connid);
    $stmt->bindParam(':conncode', $conncode);

    $fin = fopen($file, 'r') or die('Cannot open file');
    while ( false!==($data=fgetcsv($fin,5000,";")) ) {
      list($id, $code, $connid, $conncode)=$data;
      $stmt->execute();
    }
  }
}

$pdo = new PDO("mysql:host=localhost;dbname=test", 'localonly', 'localonly'); 
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
// set up a demo table and some test data
$pdo->exec('CREATE TEMPORARY TABLE dt_table_tmp (id int, code int, connectid int, connectcode int)');
$sourcepath = 'sample.data.tmp';
$fh = fopen($sourcepath, 'wb') or die('!fopen(w)');
for($i=0; $i<10000; $i++) {
  fputcsv($fh, array($i, $i%4, $i%100, $i%3), ';');
}
fclose($fh); unset($fh);
// test script
$foo = new Foo($pdo);
$foo->initiateInserts($sourcepath);

mysql veri alma hızlandırmak hakkında birkaç ipucu

  • veri gerçekten çözümlü gerektirir kontrol, bazen load data csv sadece çalışıyor
  • Mümkünse, php aracılığıyla ilk kez bir sql dosyası oluşturun ve sonra mysql komut satırı istemcisi ile çalıştırmak
  • Multivalue uçlar kullanmak
  • takmadan önce tuşları devre dışı

Multivalue insert deyimi gibi bir şeydir

INSERT INTO users(name, age) VALUES
     ("Sam", 13), 
     ("Joe", 14),
     ("Bill", 33);

Bu üç ayrı insert tablolara göre çok daha hızlıdır.

Tuşları devre dışı bırakılması Eğer bir INSERT konum her zaman dizine önlemek için önemlidir:

 ALTER TABLE whatever DISABLE KEYS;
 INSERT INTO whatever .....  
 INSERT INTO whatever .....  
 INSERT INTO whatever .....  
 ALTER TABLE whatever ENABLE KEYS;

daha fazla okuma http://dev.mysql.com/doc/refman/5.1/en/insert-speed.html

this question Sana benzer bir şey yapmak gerektiğini söyleyebilirim esinlenerek. Eğer gerçekten bu kadar çok veri varsa, o zaman bir bulk import Bunun için en uygun yaklaşımdır. Ve zaten bir dosyaya veri var.

LOAD DATA INFILE komuta bakabilirsiniz.

LOAD DATA INFILE deyimi çok yüksek bir hızda bir tabloya bir metin dosyasından satır okur. Dosya adı bir dize olarak verilmelidir.

Eğer hız farklılıkları istiyorsanız o zaman okumak Speed of INSERT Statements.

Örneğin bunu yapabilirsiniz:

$query = "LOAD DATA INFILE 'data.txt' INTO TABLE tbl_name
          FIELDS TERMINATED BY ';' 
          LINES TERMINATED BY '\r\n'
          IGNORE 1 LINES;
         "

Bu aynı zamanda sadece sütunları gösterir varsayarak ilk satırı göz ardı edecektir.