Получить вставленные записи в последнем запросе / Получить количество измененных строк (MySQL) - PullRequest
2 голосов
/ 15 марта 2019

В настоящее время я перевожу старую структуру БД на новую. Я создаю сценарий SQL (потому что мне может потребоваться выполнить эту операцию несколько раз), и я застрял на определенной операции, которую хочу выполнить.

Итак, соответствующие таблицы / поля для этого скрипта:

состояния -> старая таблица, где я собираюсь получить записи для меток

  • ID
  • * 1014 два авто *
  • color_code
  • состояние

фрилансеры -> старый стол

  • idfreelancer
  • (информация фрилансера, много неважных полей)
  • idstate

метки -> новая таблица, для хранения меток (фрилансеры могут иметь несколько меток, метки могут иметь несколько фрилансеров)

  • idlabel
  • имя
  • color_code

free_labels -> новая таблица для перекрестных ссылок на ярлыки и фрилансеров

  • idlabel
  • idfreelancer

Итак, что я хочу:

  1. Копировать каждую запись из штатов, где default_name IS NULL, в метки.
  2. Удалить каждую запись из штатов, где default_name IS NULL
  3. Если у фрилансера было состояние с именем по умолчанию NULL, его следует изменить на idstate = 1 и вставить соответствующую метку в таблицу free_labels.

Для первых 2-х пунктов я пришел с запросом:

INSERT INTO labels(name,color_code,idcreator)
SELECT state AS name,color_code,2 AS idcreator FROM states
where default_name IS NULL;

DELETE FROM states WHERE default_name IS NULL;

Я принудил idcreator к 2, и это предназначено, я знаю, это может показаться странным.


В качестве третьего пункта я подумал об использовании чего-то вроде:

INSERT INTO free_labels(idlabel,idfreelancer)
VALUES
((SELECT LAST_INSERT_ID() FROM labels),
(SELECT f.idfreelancer FROM freelancers f, states s,
WHERE f.idstate=s.id AND s.default_name IS NULL))

Примечание: Я еще не пробовал этот запрос, поэтому я даже не знаю, смогу ли я вообще сделать INSERT INTO с двойным SELECT.

И используйте этот запрос перед удалением записей из состояний. Однако у этого запроса есть 2 проблемы для меня.

  • Это не меняет состояние фрилансера,
  • И, что наиболее важно, он «ломается» для нескольких записей, поскольку LAST_INSERT_ID() получит только последнюю вставленную запись.

Я немного растерялся, как сделать эту операцию, я думаю, что это можно сделать, получив количество измененных записей из запроса, но я не знаю, возможно ли это с помощью SQL (я также могу использовать PHP хотя при необходимости я бы предпочел не делать).

Еще одна вещь, которую я рассмотрел, это то, что, возможно, я мог бы сделать INSERT с JOIN, поэтому я бы вставил записи в labels и free_labels одновременно. Но опять же, я не знаю, возможно ли это с SQL и решит ли это мою проблему.

Мне бы очень хотелось избежать переноса этих записей вручную ...

Любая помощь / предложения будут с благодарностью!

1 Ответ

1 голос
/ 15 марта 2019

Итак, прежде всего вы создаете новую таблицу меток с еще одним столбцом:

CREATE TABLE labels (
  idlabel int PRIMARY KEY AUTO-INCREMENT,
  #Some other columns....
  old_id int
  );

Затем вы вставляете данные в эту таблицу, как вы делали, плюс old_id (и удаляете строки):

INSERT INTO labels(name,color_code,idcreator,old_id)
  SELECT state AS name,color_code,2 AS idcreator, id AS old_id FROM states
  where default_name IS NULL;

DELETE FROM states WHERE default_name IS NULL;

Теперь вы можете сопоставить свой идентификатор фрилансера со старым stateid в таблице free_labels:

INSERT INTO free_labels (idlabels, idfreelancers)
  SELECT labels.idlabel, freelancers.idfreelancer 
  FROM labels 
  JOIN freelancers
  ON labels.old_id = freelancers.idstate;

Все, что вам нужно сделать сейчас, это установить idstate фрилансеров равным 1 (будьте осторожны,кстати, с состоянием с id = 1 или одним из них для проверки free_labels, в противном случае установите его в NULL или 0), удалите столбец в метках и все:

UPDATE freelancers SET idstate = 1 WHERE idfreelancer IN (SELECT idfreelancer FROM free_labels);

ALTER TABLE labels DROP COLUMN old_id;
...