2013-06-11 17 views
6

Czy w ogóle istnieje potrzeba wstawiania wstawki wielowierszowej w jednym zapytaniu bez pisania surowego kodu SQL, aby to zrobić? Opcje saveMany i saveAssociated będą zapisywać tylko wiele wierszy w pojedynczej transakcji, ale ta transakcja zawiera wiele instrukcji wstawiania, więc te metody wyraźnie nie są rozwiązaniem do pisania ciężkich aplikacji.Zapisywanie wielu wierszy w pojedynczym zapytaniu

Dzięki za przeczytanie.

Odpowiedz

0

Ktoś wskazał mi w kierunku Zachowanie Big Data https://github.com/jmillerdesign/CakePHP_Big_Data

+0

Ostrożnie =). Takie zachowanie ma (być może) poręczne API, ale IS pisze raw sql. Jeśli twoje dane nie są proste, dostaniesz błędy składni sql - robi to tylko podstawowe [cytowanie wartości] (https://github.com/jmillerdesign/CakePHP_Big_Data/blob/master/Model/Behavior/BigDataBehavior.php# L146). Wygląda na to, że nie pozwala ci nic zrobić poza wstawieniem/aktualizacją całego wiersza.Jeśli mimo wszystko chcesz go użyć, sugeruję aktualizację, aby po prostu zadzwonić pod numer [insertMulti] (https://github.com/cakephp/cakephp/blob/master/lib/Cake/Model/Datasource/DboSource.php#L2894). kwerendy sql są problemem czekającym na wystąpienie. – AD7six

+0

Dzięki za komentarz. – systematical

-1

tak można użyć jak poniżej

Sposób getDataSource() jest statyczna w CakePHP 2.x, więc powinieneś być w stanie używać:

$db = ConnectionManager::getDataSource('default'); 
$db->rawQuery($some_sql); 

jestem tutaj metodę zrobić delegowania. musisz ręcznie utworzyć instrukcję SQL, aby wstawić wiele wierszy jednocześnie.

Proszę dać mi znać, czy mogę Ci pomóc.

+1

-1 'bez pisania surowego kodu SQL, aby to zrobić?' – AD7six

+0

Wiem, jak zrób to z tradycyjnym SQL, chcę pozostać w mojej strukturze. Surowy SQL jest ostatecznością. Znalazłem to: https://github.com/jmillerdesign/CakePHP_Big_Data – systematical

3

Tak

Choć nie jest to powszechną praktyką, aby to zrobić w kodzie app-lądowego, a robi tak usuwa możliwość korzystania prawie każdy logiki aplikacji (reguły sprawdzania poprawności, zachowań, zdarzeń etc.). Można zobaczyć przykład robi to w sposób fixtures are loaded:

$db = ConnectionManager::getDataSource('default'); 

$table = "stuffs"; 
$fields = array('id', 'name'); 
$values = array(
    array(1, 'one'), 
    array(2, 'two'), 
    ... 
); 

$result = $db->insertMulti($table, $fields, $values); 

Można również znaleźć this repository użytecznych (bezpośrednio lub jako podstawa do kodu), który ładuje pliki osprzętu do bazy danych aplikacji - przy użyciu standardowej wkładki .

+1

wygląda na to, że nadal wstawia pojedynczy wiersz na raz zawinięty w jedną transakcję ... – systematical

+0

Hah! [Nie zauważyłem tego] (https://github.com/cakephp/cakephp/blob/master/lib/Cake/Model/Datasource/DboSource.php#L2917). Jeśli robisz to wystarczająco często, aby coś zmienić, jak zauważono w komentarzu do odpowiedzi na pytanie o zachowanie dużych danych, upewnij się, że wybrane rozwiązanie odpowiednio usuwa wartości. – AD7six

1

Tak, Big_Data jest dobrym pomysłem na wstawianie luzem. Ale jak zauważa AD7six, nadal używa on podstawowej wartości i nie zwraca identyfikatorów insertów. Opierając się na twoich pomysłach, napisałem mały skrypt do wstawiania luzem w pojedynczym zapytaniu, używając domyślnego cytowania CakePHP i zwracania identyfikatorów wstawionych rekordów.

$count = count($records); 
    $dbSource = $this->getDataSource(); 
    $table = $dbSource->fullTableName($this->table); 
    $fields = $dbSource->prepareFields($this, array('fields' => array_keys($records[0]))); 
    $values = array(); 
    foreach ($records as $index => $record) { 
     if (!is_array($record) || !$record) { 
      return null; 
     } 
     foreach ($record as $column => $value) { 
      $values[$index][$column] = $dbSource->value($value, $this->getColumnType($column)); 
     } 
     $values[$index] = '(' . implode(',', $values[$index]) . ')'; 
    } 

    $query = 'INSERT INTO %s (%s) VALUES %s;'; 

    $query = sprintf($query, $table, implode(',', $fields), implode(',', $values)); 
    if (!$dbSource->execute($query)) { 
     return false; 
    } 
    $lastInsertId = $dbSource->getConnection()->lastInsertId(); 
    $insertIds = array(); 
    for ($i = 0; $i < $count; $i++) { 
     $insertIds[] = $lastInsertId + $i; 
    } 
    return $insertIds; 
Powiązane problemy