简体   繁体   中英

PDO SQL single query, multiple rows and values

I have this array JSON POST request to a PHP file.

Array
(
[user_id] => 1
[date] => 2014-12-05
[time] => 12:00
[description] => lol
[friends] => "12","9"
[PHPSESSID] => 5ae7c3e6339c528e7804020dd0f0cdbb
)

I try to add the values (12 | 1) and (9 | 1) to a mysql table with a single sql query

Table:

u_id  |  f_id
  1   |   12
  1   |   9

What I have so far:

$friendarray = $_POST['Friends'];

foreach( $friends as $friendsarray ) {
    $values[] = "(" . $u_id . "," . $friendsarray . ")";
    }

$query = "INSERT INTO up2_friends_to_users (u_id , f_id ) VALUES ".implode(',',$values);

    $stmt   = $db->prepare($query);
    $result = $stmt->execute();

As you see this is not working at all. I try to achieve something like this:

$query_params = array(
    ':u_id' => $_POST['user_id'],
    ':f_id' => $friendid,

And then would like to send it like this:

    $stmt   = $db->prepare($query);
    $result = $stmt->execute($query_params);

Is it possible to create a single query with multiple rows like this?

Answer thanks to RobP:

        $friendsarray = explode(',',$_POST['friends']);
        $placeholders = [];

        for($i=0, $len=count($friendsarray); $i < $len; $i++) {
            $placeholders[i] .= "(:u_id".$i.", :f_id".$i.")"; // entries like "(:u_id0, :f_id0)"
        }
        $query = "INSERT INTO up2_friends_to_users (u_id , f_id ) VALUES  ".implode(",", $placeholders);
        $stmt = $db->prepare($query);
        for($i=0, $len=count($placeholders); $i < $len; $i++) {
            $stmt->bindParam(':u_id'.$i, $_POST['user_id']);
            $nextFriend = $friendsarray[$i];
            $stmt->bindParam(':f_id'.$i,trim($nextFriend,'"'));
        }
        $result = $stmt->execute(); 

Now f_id is always null.

I agree the best strategy is to use a single query as you were trying to do. This will be much faster for long lists, especially if you don't wrap all the individual inserts into a single commit. This should work:

$friendarray = $_POST['Friends'];
$placeholders = [];
$user_id = $_POST[`user_id`];

for($i=0, $len=count($friendarray); $i < $len; $i++) {
    $placeholders[$i] = "(:u_id".$i.", :f_id".$i.")"; // entries like "(:u_id0, :f_id0)"
}

$query = "INSERT INTO up2_friends_to_users (u_id , f_id ) VALUES ".implode(",", $placeholders);
$stmt = $db->prepare($query);
for($i=0, $len=count($placeholders); $i < $len; $i++) {
    // each binding must use a separate variable, not an array element
    $stmt->bindParam(':u_id'.$i, $user_id);
    // use your favorite escape function on the value here
    $nextFriend = $db->real_escape_string($friendarray[$i]);
    $stmt->bindValue(':f_id'.$i, $nextFriend);
}

EDIT: learned something new from Only variables can be passed by reference - php . Can't pass array elements to bindParam as second parameter! Workaround posted above.

Do this:

$query = "INSERT INTO up2_friends_to_users (u_id , f_id ) VALUES (:u_id, :f_id)";
$stmt = $db->prepare($query);
$stmt->bindParam(':u_id', $_POST['user_id'];
$stmt->bindParam(':f_id', $friendid);

foreach ($_POST['Friends'] as $friendid) {
    $stmt->execute();
};

bindParam binds to a reference, so every time you execute the query it will use the value of $friendid from the current iteration of the loop.

Maybe, something like this (using question mark parameters)?

$values = array();
foreach ($_POST['Friends'] as $friendid) {
    $values[] = $u_id;
    $values[] = $friendid;
}

$conn = new \PDO($dsn, $user, $password);
$query = 'INSERT INTO up2_friends_to_users (u_id , f_id ) VALUES '
        . trim(str_repeat('(?, ?),', count($values / 2)), ',');
$conn->prepare($query)->execute($values);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM