переместить строку между таблицами

0

Я хочу переместить строку из posts в archive. Обе таблицы имеют одинаковые столбцы.

$st = $db->query("select * from posts where id = " . $id);
while ($row = $st->fetch()){
    $date = $row['date']; ...

$sql = "insert into archive (date,...) values (:adate,...)";

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

$st->execute(array(
    ":adate" => $date, ...

$st = $db->query("delete from posts where id = " . $id);

столбец id автоматически увеличивается на обе таблицы.

Есть ли более короткий способ сделать это, потому что есть 14 столбцов на каждой таблице?

  • 0
    Поддерживает ли PHP пакетную вставку?
  • 1
    Существует оператор INSERT .... SELECT поэтому база данных может сделать это за один раз. Dev.mysql.com/doc/refman/5.7/en/insert-select.html
Теги:

2 ответа

1
Лучший ответ

Пока столбцы имеют одни и те же типы и в том же порядке, вы можете insert into archive select * from posts where id = :id. Однако это будет вставляться в archive с тем же идентификатором.

    MariaDB [temp]> select * from posts;
    +------+-------+-------+
    | id   | a     | b     |
    +------+-------+-------+
    |    2 | test3 | test4 |
    |    1 | test  | test2 |
    +------+-------+-------+
    2 rows in set (0.00 sec)

    MariaDB [temp]> select * from archive;
    Empty set (0.00 sec)

    MariaDB [temp]> insert into archive select * from posts where id = 2;
    Query OK, 1 row affected (0.05 sec)
    Records: 1  Duplicates: 0  Warnings: 0

    MariaDB [temp]> select * from archive;
    +------+-------+-------+
    | id   | a     | b     |
    +------+-------+-------+
    |    2 | test3 | test4 |
    +------+-------+-------+
    1 row in set (0.01 sec)

    MariaDB [temp]> 

Если вы хотите, чтобы автоколонка id автоматически включалась, вам нужно будет выбрать каждый столбец, такой как insert into archive (date,...) select (date,...) from posts where id = :id

    MariaDB [temp]> select * from posts;
    +------+------+-------+
    | id   | a    | b     |
    +------+------+-------+
    |    1 | test | test2 |
    +------+------+-------+
    1 row in set (0.00 sec)

    MariaDB [temp]> select * from archive;
    +----+-------+-------+
    | id | a     | b     |
    +----+-------+-------+
    |  2 | test3 | test4 |
    +----+-------+-------+
    1 row in set (0.00 sec)

    MariaDB [temp]> insert into archive (a, b) select a, b from posts where id = 1;
    Query OK, 1 row affected (0.02 sec)
    Records: 1  Duplicates: 0  Warnings: 0

    MariaDB [temp]> select * from archive;
    +----+-------+-------+
    | id | a     | b     |
    +----+-------+-------+
    |  2 | test3 | test4 |
    |  3 | test  | test2 |
    +----+-------+-------+
    2 rows in set (0.00 sec)

    MariaDB [temp]> 
  • 0
    не могу поверить, что нет способа move all except id from table to table . В любом случае, большое спасибо за ваши усилия.
0

На самом деле, я предлагаю вам использовать следующий подход:

$ids = array(3, 7, 15, 31, 45);
$clause = implode(',', array_fill(0, count($ids), '?'));

$stmt = $mysqli->prepare('INSERT INTO Archive SELECT Field1, Field2, Field3 FROM Posts WHERE 'id' IN ('.$clause.');');
call_user_func_array(array($stmt, 'bind_param'), $ids);
$stmt->execute();

$stmt = $mysqli->prepare('DELETE FROM Posts WHERE 'id' IN ('.$clause.');');
call_user_func_array(array($stmt, 'bind_param'), $ids);
$stmt->execute();

Инструкция IN позволяет избежать использования одного запроса для каждого идентификатора, в то время как INSERT INTO позволяет избежать выполнения выбора для каждой вставки. В целом производительность вашего процесса должна быть улучшена.

Вдобавок ко всему, я рекомендую вам выполнить все это в рамках TRANSACTION, так что ваши таблицы не будут перепутаны, если один из двух запросов завершится с ошибкой или если ваш сервер столкнулся с проблемой.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню