如何使用MySQLi预处理语句执行具有可变数量占位符的多个INSERT?

时间:2014-06-24 10:49:23

标签: php mysql prepared-statement

有关如何使用MySQLi 预处理语句执行多个INSERTs同时拥有可变数量(大约40个)占位符的任何想法?

我知道如何使用可变数量的占位符制作预准备语句:

array_unshift($paramValues, str_repeat('s', count($paramValues)));
call_user_func_array(
    [$statement, 'bind_param'],
    sql::makeValuesReferenced($paramValues)
);

我也知道如何进行多次执行:

$statement->bind_param('i', $id);
for ($id=0, $id<10, ++$id) {
    $statement->execute();
}

但我无法将自己的思维结合到单一的方法中。

基本上,我有数组的数据,我想要INSERT到数据库,而不必手动硬编码变量。我想要函数,我把数据放在数组中,函数将负责绑定和执行。

$data = [
    0 => [a => aaa, b => bbb],
    1 => [a => ccc, b => ddd],
];

(我使用的是PHP 5.5和MySQL 5.5。)

1 个答案:

答案 0 :(得分:0)

您只需准备一次sql,然后多次重复bind_param()execute()。虽然我认为你已经有了。

所以使用你的示例输入

$data = [
    0 => [a => aaa, b => bbb],
    1 => [a => ccc, b => ddd],
];

// get a list of all the field names
// and also build the question mark list
$fields = '';
$qMarks = '';

foreach ( $data[0] as $field => $val ) {
    $fields .= $field . ',';
    $qMarks .= '?,';
}
rtrim($fields, ',');
rtrim($qMarks, ',');

/* 
   Build the datatype list:

   Replace commas with nothing and ? with s
   THIS WILL ONLY WORK IF YOUR DATATYPES ARE ALL THE SAME

   If you also had the datatypes in your $data array this 
   would obviously work better, or rather be more flexible

   I THINK THIS IS THE FLY IN THE OINTMENT!!
*/

$datatypes = '';
$datatypes = str_replace(array(',','?'),array('','s'),$qMarks);

$sql = "INSERT INTO TABLE table ($fields) VALUES($qMarks)";

$stmt = $db->prepare($sql);


foreach ($data as $row ) {

    $params = array();
    foreach ( $row as $name => $val ) {
        $params[] = $val;
    }

    $stmt->bind_param($datatypes, $params);
    $result = $stmt->execute();

    if ( ! $result ) {
        // You have an error, deal with it here and probably stop the loop
    }
}