Я помогал своим коллегам с проблемой SQL. В основном они хотели переместить все строки из таблицы A в таблицу B (обе таблицы имеют одинаковые столбцы (имена и типы)). Хотя это было сделано в Oracle 11g, я не думаю, что это действительно имеет значение.проблема изоляции транзакций или неправильный подход?
Их первая наивная реализация была что-то вроде
BEGIN
INSERT INTO B SELECT * FROM A
DELETE FROM A
COMMIT;
END
их озабоченность, если были Вставки в таблицу А во время копирования от А до В и «DELETE FROM A» (или TRUNCATE для того, что стоит) приведет к потере данных (с добавлением новых вставленных строк в A).
Конечно, я быстро рекомендовал хранить идентификаторы скопированных строк во временной таблице, а затем удалять только строки из A, которые соответствуют IDS во временной таблице.
Однако, ради любопытства, мы немного подходим к тестированию, добавляя команду ожидания (не помните синтаксис PL/SQL) между INSERT и DELETE. Тогда из другого соединения мы вставляем строки ВО ВРЕМЯ ЖДЕТ.
Мы заметили, что это было потерей данных. Я воспроизвел весь контекст в SQL Server и завернул все это в транзакцию, но все же свежие новые данные были потеряны и в SQL Server. Это заставило меня думать, что в первоначальном подходе происходит систематическая ошибка/недостаток.
Однако я не могу сказать, был ли тот факт, что TRANSACTION не был (каким-то образом) изолирован от новых новых INSERT или фактом, что INSERT пришли во время команды WAIT.
В конце концов, это было реализовано с использованием временной таблицы, предложенной мной, но мы не смогли получить ответ на вопрос «Почему потеря данных». Ты знаешь почему?
Я иду с @Guy. Гораздо лучше сделать все явным и очевидным. Выполнение этого с использованием SQL там, где это возможно, менее загадочно, чем использование уровней изоляции (если вы можете это сделать, конечно). – 2008-09-30 09:35:27
Синтаксис неверен: «... где существует (выберите B. из B, где B. = A. ) –
2009-07-05 11:29:06