PDO ile SQL Tabloların Düzenlenmesi

4 Cevap php

Benim kod şöyle görünür:

// Connect to SQLite DB
DB('/path/to/sqlite.db');

DB('BEGIN TRANSACTION;');

// These loops are just examples.
for ($i = 1; $i <= 10000; $i++)
{
    for ($j = 1; $j <= 100; $j++)
    {
    	DB('INSERT INTO "test" ("id", "name") VALUES (?, ?);', $i, 'Testing ' . $j);
    }
}

DB('END TRANSACTION;');

Ve burada DB () fonksiyonu:

function DB($query)
{
    static $db = null;

    if (is_file($query) === true)
    {
    	$db = new PDO('sqlite:' . $query, null, null, array(PDO::ATTR_ERRMODE => PDO::ERRMODE_WARNING));
    }

    else if (is_a($db, 'PDO') === true)
    {
    	$result = $db->prepare($query);

    	if (is_a($result, 'PDOStatement') === true)
    	{
    		if ($result->execute(array_slice(func_get_args(), 1)) === true)
    		{
    			if (stripos($query, 'INSERT') === 0)
    			{
    				return $db->lastInsertId();
    			}

    			if (stripos($query, 'SELECT') === 0)
    			{
    				return $result->fetchAll(PDO::FETCH_ASSOC);
    			}

    			return $result->rowCount();
    		}
    	}

    	return false;
    }

    return true;
}

Sorun iç döngü içinde DB () çağrısı Ben böyle bir şey yaptığını ölçüde yürütme hızlandırmak diye düşünüyordum, tamamlamak için uzun alıyor olmasıdır:

DB('BEGIN TRANSACTION;');

for ($i = 1; $i <= 10000; $i++)
{
    $queries = array();

    for ($j = 1; $j <= 100; $j++)
    {
    	$queries[] = 'INSERT INTO "test" ("id", "name") VALUES (?, ?);' /*, $i, 'Testing ' . $j;*/
    }

    DB(implode("\n", $queries));
}

DB('END TRANSACTION;');

Sorun, ben bunu gerçekleştirmenin bir yolu yoktur, ilgili değişkenleri ile tüm soru işaretleri (yerine kaçmayı) ben hazırlamak nasıl bilmiyorum?

4 Cevap

Bir tabloya veri çok ekliyorsanız, bir sorgudaki verileri eklemeyi deneyin.

$query = 'INSERT INTO "test" ("id", "name") VALUES ';
$data = array();
for ($i = 1; $i <= 10000; $i++) {
  for ($j = 1; $j <= 100; $j++) {
    $query .= '(?,?),';
    $data[] = $i;
    $data[] = 'Testing '.$j;
  }
}

$query = substr($query, 0, -1);
DB($query, $data);

This should eliminate the overhead with single insert queries. There's a limit on the query lenght though, if you have troubles with query lenght, try issueing DB() calls more often in for loop.

Eğer döngü onları "hazırlamak", neden hazırlanmış deyimleri kullanılır? (DB fonksiyonunda)

Make a prepare befor the loop, and in the loop just give the values and execute. Of course this would require a rewrite of your DB method.

Oh söyliyim. Kimlik sütunu birincil anahtar? böylece eğer başka bir sorun danışmanın var "i" 100 "j" aynı :) için olacak

Örneğin:

$sth = $dbh->prepare('INSERT INTO "test" ("id", "name") VALUES (:id, :name)');
$j=0;
for ($i = 1; $i <= 10000; $i++){
   $j = ($j==100) ? 0 : $j++;
   $sth->execute(array(':id' => $i, ':name' => 'Testing ' . $j));     
}

Ne yazık ki sorun kod yapısı ile olabileceğini düşünüyorum.

INSERT deyimleri sizin döngüde ifadeler aynıdır ve her zaman hazırlar db-> $ aramaya gerek yoktur. Hazırlanan tabloların arkasındaki fikir () aynı deyimi nesne üzerinde birden çok kez çağrılabilir kez () db-> prepare $ çağrı ve yürütmek olmasıdır. SQL deyimini ayrıştırma ve yeni bir nesne oluştururken yükü neden olan) her zaman, ($ db-> prepare diyorlar.

Bu gibi DB () fonksiyonu re-yazma düşünün:

function do_query($db, $pdo_statement, $query, $args)
{
    if ($pdo_statement->execute($args) === true)
    {
        if (stripos($query, 'INSERT') === 0)
        {
          return $db->lastInsertId();
        }
        if (stripos($query, 'SELECT') === 0)
        {
          return $result->fetchAll(PDO::FETCH_ASSOC);
        }
        return $result->rowCount();
    }
}

function DB($query)
{
    static $db = null;

    if (is_file($query) === true)
    {
      $db = new PDO('sqlite:' . $query, null, null, array(PDO::ATTR_ERRMODE => PDO::ERRMODE_WARNING));
    }

    else if (is_a($db, 'PDO') === true)
    {
      $result = $db->prepare($query);

      if (is_a($result, 'PDOStatement') === true)
      {
        $args = func_get_args();
        if (is_array($args[1])) {
            $ret = array();
            foreach ($args[1] as $args) {
                $ret[] = do_query($db, $query, $result, $args);
            }
            return $ret;
        }

        return do_query($db, $query, $result, array_slice(func_get_args(), 1));
      }

      return false;
    }

    return true;
}

Eğer değerler sürü ile aynı sorguyu çalıştırmak istiyorsanız Yani, iki boyutlu eklemek istediğiniz değerler dizisi ve çağrı DB('INSERT INTO....', $values) oluşturun. DB () function ($ sorgu sonrası) fonksiyonuna ikinci parametre bir dizi olup olmadığını görmek için kontrol eder ve bu yüzden dizideki değerlere karşı koşu $ sorgusu aracılığıyla döngüler halinde. Bu şekilde, döngü sadece farklı değerleri ile yeniden çalıştırmak, SQL deyimini her defasında yeniden hazırlanması anlamına gelmez. Işlevin dönüş değeri, her sorgu sonuçlarının bir dizi olacak.

DB işlevi olarak başlangıçta yaşanan sorunlar bir dosya sistemi stat () sistem çağrısı bu sorgu dizesi bir dosya olup olmadığını kontrol etmek için her çalıştırıldığında yayınlanmıştır. Bu yavaş yürütülmesi için tek başına sorumlu değildir, bunun katkıda bulunur.