2009-05-03 109 views
21

我有信息的數組,看起來或多或少是這樣的:如何用Zend_Db添加多行?

$data[] = array('content'=>'asd'); 
$data[] = array('content'=>'asdf'); 

而且我想這兩個條目添加到數據庫中。

$db->insert('table', $data); 

不添加兩個條目。我究竟做錯了什麼?我必須使用Zend_Db_Table嗎?

$data = array('content'=>'asdf'); 
$db->insert('table', $data); 

作品當然

+3

在Zend的2.0([ZF2-475](多插入功能請求http://framework.zend.com/issues/browse/ZF2-475))已經關閉爲wontfix。 – Tgr 2012-12-18 11:07:53

回答

32

的,我不認爲Zend_Db的支持多行插入。

但是,如果你只有兩行或多一點,你可以使用一個循環。

foreach ($data as $row) 
{ 
    $db->insert('table', $row) 
} 


Bill Karwin,前Zend Framework的開發者,寫道 this on Nabble some time ago

行集基本上是一個集合對象,所以我想補充方法的那類,以允許行被添加到組。所以,你應該能夠做到這一點:

// creates a rowset collection with zero rows 
$rowset = $table->createRowset(); 

// creates one row with unset values 
$row = $table->createRow(); 

// adds one row to the rowset 
$rowset->addRow($row); 

// iterates over the set of rows, calling save() on each row 
$rowset->save(); 

這是沒有意義傳遞給createRowset一個整數(),以創建n個空行。無論如何,您只需遍歷它們就可以用值填充它們。因此,您不妨編寫一個循環來創建和填充應用程序數據的各個行,然後將它們添加到集合中。

$rowset = $table->createRowset(); 
foreach ($appData as $tuple) 
{ 
    $row = $table->createRow($tuple); 
    $rowset->addRow($row); 
} 
$rowset->save(); 

應當把它以允許數組的數組要傳遞給createRowset(),因爲這將是與通過一個元組到createRow的使用是一致的()。

$rowset = $table->createRowset($appData); // pass array of tuples 

這將執行相同的循環與上述前面的例子(除了保存()結尾),創建的新行的新行集,準備保存()d。

有在SQL兩種方式來提高插入數據的效率:

  1. 使用一個INSERT語句具有多個行:

    INSERT INTO T(COL1,COL2,COL3)VALUES( (4,5,6),(7,8,9);

  2. 準備一個INSERT語句並執行多次:

    PREPARE INSERT INTO噸(COL1,COL2,COL3)VALUES;(,,????) EXECUTE 1,2,3 EXECUTE 4,5,6 EXECUTE 7,8,9

然而,支持任一這些改進將增加複雜性,以行和行集類。這是由於當前Zend_Db_Table_Row類在調用save()時需要插入或更新的行之間的內部方式。此區別由Row對象封裝,因此Rowset不知道各個行是新行還是現有行的已修改副本。因此,爲了使Rowset類提供使用更高效SQL的多行save()方法,髒數據的管理必須完全重構。更簡單的解決方案是Rowset迭代其行,並在每個行上調用save()。這對於OO封裝來說更好,儘管它無法優化插入行集的SQL。

在任何情況下,在高效SQL最需要的時候,在典型的Web請求中批量加載多行數據實屬罕見。少數行的效率差異很小,所以只有在批量加載大量行時纔會有顯着的改進。如果是這種情況,那麼不應該使用INSERT,如果您使用其他RDBMS品牌,則應該使用MySQL的LOAD DATA語句或等效功能。 INSERT通常不是加載大量數據的最有效選擇。

關於返回自動生成的密鑰,我不打擾。注意,如果您使用普通SQL(例如在mysql CLI中),並且您在單個INSERT語句中插入多行,則只能獲取最後生成的id值,而不能插入所有行的id值。這是SQL行爲;任何語言或任何框架都是如此。

INSERT INTO t (col1, col2, col3) VALUES (1, 2, 3), (4, 5, 6), (7, 8, 9); 
SELECT LAST_INSERT_ID(); -- returns only the id for the third tuple 

如果你需要爲每個行的ID,你應該寫一個循環並插入行一次一個,檢索插入每一行後生成的ID。

+0

這是不正確的:$ sql =「INSERT INTO beautiful(name,age) VALUES ('Helen',24), ('Katrina',21)」;作品(只是一個例子) – Thomaschaaf 2009-05-03 12:37:20

+0

你是對的。我仍然不認爲zf支持它,手冊中的任何地方都沒有提示。但我不確定。 – markus 2009-05-03 13:35:56

+1

哈哈!我希望我已經有機會獲得讚揚! Tharkun幹得好,找到並重新發布。 – 2009-05-03 23:48:40

18

您可以通過Zend_Db_Adapter_Abstract::query()方法執行所需的任何SQL語法 - 包括多行INSERT語句。

Zend_Db_TableZend_Db_Table_Rowset類的方法不支持一次插入多行。

10

插入多行,你可以使用Zend_Db的

$stmt = $table->getAdapter()->prepare('INSERT INTO tablename (col1, col2, col3) VALUES (?, ?, ?), (?, ?, ?)'); 

$stmt->execute(array($value1, $value2, $value3, $value4, $value5, $value6)); 

(比爾Karwin)

在你的情況下,我們可以改變這個代碼:

$data[] = array('content'=>'asd'); 
$data[] = array('content'=>'asdf'); 

$stmt = $table->getAdapter()->prepare('INSERT INTO table (col1) VALUES (?), (?)'); 
$stmt->execute($data); 

產生這些' (?),(?)'動態,如果數據是動態的,您可以嘗試使用此代碼段:

$values = implode(',',array_fill(0,count($data),'(?)')); 

希望這有助於

問候, Riki的Risnandar

1

如果你使用ZF2那麼解決辦法可能是這樣的:

$insert = $this->getSql()->insert(); 
foreach ($values as $value) { 
    $relation = array(
     'column_one' => $value, 
     'column_two' => $value 
    ); 
    $insert->values($relation, Insert::VALUES_MERGE); 
} 

$insertRes = $this->executeInsert($insert); 
1

這是工作。

$query = 'INSERT INTO ' . $db->quoteIdentifier('table') . ' (`col1`, `col2`) VALUES '; 
    $queryVals = array(); 
    foreach ($data as $row) { 
     foreach($row as &$col) { 
      $col = $db->quote($col); 
     } 
     $queryVals[] = '(' . implode(',', $row) . ')'; 
    } 
    $stmt = $db->query($query . implode(',', $queryVals)); 

how to build multiple insert query in zend framework

2

這裏是我的解決方案:

public function saveRows($array) { 
     $vAmount = count($array); 
     $values  = array(); 
     $columns = array(); 

     foreach ($array as $colval) { 
      foreach ($colval as $column=>$value) { 
       array_push($values,$value); 
       !in_array($column,$columns) ? array_push($columns,$column) : null; 
      } 
     } 

     $cAmount = count($columns); 
     $values  = array_chunk($values, $cAmount); 
     $iValues = ''; 
     $iColumns = implode("`, `", $columns); 

     for($i=0; $i<$vAmount;$i++) 
      $iValues.="('".implode("', '", $values[$i])."')".(($i+1)!=$vAmount ? ',' : null); 

     $data="INSERT INTO `".$this->_name."` (`".$iColumns."`) VALUES ".$iValues; 
     die($data); 
     $this->query($data); 
    }