簡體   English   中英

如何在PHP中執行多個MySQL插入

[英]How to perform multiple MySQL inserts in PHP

我需要在MySQL表中插入許多行(150到300之間),我想知道以下方法在性能方面更好:

方法1:

foreach( $persons as $person ){

       $stmt = $dbLink->prepare( "INSERT INTO table SET id = :ID, 
                                                 name = :name, 
                                                 email = :email, 
                                                 mobile = :mobile");
       $stmt->execute( array( ':ID'=>$person->getID(),
                              ':name'=>$person->getName(),
                              ':email'=>$person->getEmail(),
                              ':mobile'=>$person->getMobile(),
                              ) );
}

方法2:

$stmt = $dbLink->prepare( "INSERT INTO table SET id = :ID, 
                                                 name = :name, 
                                                 email = :email, 
                                                 mobile = :mobile");

$stmt->bindParam( ':ID', $person->getID(), PDO::PARAM_STR );
$stmt->bindParam( ':name', $person->getName(), PDO::PARAM_STR );
$stmt->bindParam( ':email', $person->getEmail(), PDO::PARAM_STR );
$stmt->bindParam( ':mobile', $person->getMobile(), PDO::PARAM_STR );

foreach( $persons as $person ){

       $stmt->execute(); 
}

它是對數據庫的調用量之所以產生差異。 盡可能減少通話量。

而不是這個:

insert (a,b,c) values (d,e,f); 
insert (a,b,c) values (g,h,i); 
insert (a,b,c) values (j,k,l); 
insert (a,b,c) values (m,n,o);

做這個:

insert (a,b,c) values (d,e,f),(g,h,i),(j,k,l),(m,n,o);

因此,在一個電話中,您將在4個電話中做什么。

要回答您的問題,這是構建准備/綁定/執行階段的方式:

//prepare the query only the first time
$stmt = $dbLink->prepare( "INSERT table (id, name, email, mobile) 
                           VALUES (:ID, :name, :email, :mobile)" ); 


//bind params and execute for every person   
foreach( $persons as $person ){
    $stmt->bindValue( ':ID', $person->getID(), PDO::PARAM_STR );
    $stmt->bindValue( ':name', $person->getName(), PDO::PARAM_STR );
    $stmt->bindValue( ':email', $person->getEmail(), PDO::PARAM_STR );
    $stmt->bindValue( ':mobile', $person->getMobile(), PDO::PARAM_STR );

    $stmt->execute(); 
}

如果你有PDO::ATTR_EMULATE_PREPARES = false ,那么第一次只能通過mysql編寫查詢。

在第一種情況下,它將為每個循環周期重新准備

正如其他用戶所說的那樣,請記住,更好的性能改進是在for循環中只進行一次插入而不是多次插入


編輯:如何使用參數綁定和一個查詢

要使用參數的綁定和只有一個查詢,解決方案可能是:

$placeholders = "";    //this will be filled with placeholders : ( :id_1, :name_1, :email_1, :mobile_1),( :id_2 ... )
$parameters = array(); //this will keep the parameters bindings

$i = 1;
foreach( $persons as $person )
{
    //add comma if not first iteration
    if ( $placeholders )
        $placeholders .= ", ";

    //build the placeholders string for this person
    $placeholders .= "( :id_$i, :name_$i, :email_$i, :mobile_$i )";

    //add parameters for this person
    $parameters[":id_$i"] = $person->getID(); 
    $parameters[":name_$i"] = $person->getName(); 
    $parameters[":email_$i"] = $person->getEmail(); 
    $parameters[":mobile_$i"] = $person->getMobile(); 

    $i++;
}

//build the query
$stmt = $dbLink->prepare( "INSERT INTO table (id, name, email, mobile) 
                           VALUES " . $placeholders );

//execute the query passing parameters
$stmt->execute( $parameters );

在循環的第一部分中,我們使用一組占位符為每個人構建字符串$placeholders符,在循環的第二部分中,我們將占位符值的綁定存儲在$parameters數組中

在循環結束時,我們應該設置所有占位符和參數,並且我們可以執行將$parameters數組傳遞給execute方法的查詢。 這是使用bindValue / bindParam方法的另一種方法,但結果應該相同

我認為這是使用參數綁定的唯一方法,並且只使用一個查詢

您可以使用以下代碼來避免多個SQL調用,並在Single SQL調用中插入數據

$first_string = "INSERT INTO table (id, name, email,mobile) VALUES ";//Basic query
foreach( $persons as $person )
{
    $first_string .="(".$person->getID().",".$person->getName().",".$person->getEmail().",".$person->getMobile()."),";//Prepare the values
}

$final_query_string = substr($first_string, 0,-1);// This will remove the extra , at the end of the string

$stmt = $dbLink->prepare($final_query_string);
$stmt->execute(); 

現在執行准備的最終查詢字符串。

這樣,查詢就會被准備為字符串,您需要一次性執行它。 這將進行單個SQL調用

//declare array of values to be passed into PDO::Statemenet::execute()
$values = array();

//prepare sql string
$sql = 'INSERT INTO students ( id, name, email, mobile ) VALUES ';

 foreach( $students as $student ){

      $sql .= '( ?, ?, ?, ? ),';  //concatenate placeholders with sql string  

      //generate array of values and merge with previous values 
      $values = array_merge( $values,  array(  $student->getID(), 
                                               $student->getName(),
                                               $student->getEmail(),                       
                                               $student->getMobile(),
                                            )
                           );
 }

 $sql = rtrim( $sql, ',' );   //remove the trailing comma (,) and replace the sql string
 $stmt = $this->dbLink->prepare( $sql );            
 $stmt->execute( $values );

所有激勵我達成此解決方案的人都可以獲得全額學分。 這看起來簡潔明了:

特別是, 在單個查詢中PDO准備插入多行的JM4的答案確實有幫助。 我也在這個頁面上認出了Moppo。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM