2017-01-10 9 views
0

У меня есть пример набора данных:SQL Обновление набора записей на основе изменения в одной области

seq id status in_process processed 
3 A  N  T   F 

Это макет из промежуточной таблицы я использую по расписанию. Это довольно сложно, но я надеюсь, что этого достаточно, чтобы понять суть.

Обработка этой записи происходит каждые 15 минут. Для заданного «id» записи обрабатываются в порядке seq от самого низкого до самого высокого. Если status = 'N' (новый), запись будет обработана. Если вышеуказанная запись встречается в это время он запускается, данные идентификаторы будут обрабатываться и обрабатываться будут обновлены «T»

Позже, если ниже встречается ...

seq id status in_process processed 
5 A  D  T   F 

идентификатор будет обработан и адресат будет проинформирован о новом статусе = «D» (удалено), переработанный будет обновлен до «T»

Но если вместо этого, происходит следующее между запусками:

seq id status in_process processed 
5 A  D  T   F 
3 A  N  T   F 

Я хочу, чтобы обработка не выполнялась и просто обновление обрабатывалось до 'T'

Учитывая последний сценарий, какой запрос обновления я могу использовать? Я хочу по существу сказать

update myTable set processed = 'T' where {processed = 'F' and status was N and is now D for a given id} 

Это последняя часть фигурных скобок, которую я не знаю, как писать. Поскольку тот же идентификатор не будет иметь статус N после состояния D, мне необязательно ссылаться на значение seq, если status = 'N' и обработан = 'F' для одного и того же идентификатора, который я планирую обновить. Например, в следующем примере я хотел бы обновить id A и D1 без обработки и оставить записи B и C в одиночку с обновлением.

seq id status in_process processed 
8 D1 D  T   F 
7 D1 N  T   F 
6 C  D  T   F 
5 A  D  T   F 
4 B  N  T   F 
3 A  N  T   F 

Любая помощь будет оценена по достоинству.

+0

Это похоже на еще одну проблему, которую я опубликовал здесь некоторое время назад и задаюсь вопросом, можно ли tweeked следующее. Я думаю, что это сработает, если меня беспокоят только два состояния (N и D), но у меня также есть A, о которых нужно беспокоиться. Если D встречается до обработки N, то A также следует пометить как обработанную. 'update myTable set обрабатывается = 'T', in_process = 'T', где status = 'D' и обрабатывается = 'F' и (seq, id) in (выберите seq, id из myTable, где status = 'N' и обработан = 'F') ' – Tom

+0

Я понимаю, что указанное выше обновление не будет работать для сценария только для состояний N и D. .. любая помощь приветствуется :) – Tom

ответ

0

Один из подходов может заключаться в использовании INSTEAD OF INSERT -Trigger, который контролирует, должна ли быть вставлена ​​новая запись или существующая, должна быть обновлена.

В качестве INSTEAD OF INSERT -Trigger в Oracle может быть определен только для представлений (а не для таблиц), можно было бы сделать следующее:

  1. Переименов таблицу в staging_data и создать представление staging, например как create view staging as (select * from staging_data). Таким образом, ваше приложение будет вставляться в представление, и вызовет ваш конкретный код.

  2. В коде триггера, использовать :new -attributes и select -statements на базовой таблице staging_data данных, чтобы определить, должно ли быть выполнено обновления или вставки.

  3. Наконец, выполните ввод или обновление.

К сожалению, у меня нет среды для записи триггера и попробуйте его; Надеюсь, что это поможет. Примите, например, SO ответ Oracle view not updatable, advice on Instead Of triggers или обратитесь к Google.

+0

Спасибо, Стивен. К сожалению, среда, в которой я работаю, немного ограничена, когда мы пытаемся ограничить объекты на стороне базы данных. Можете ли вы сказать мне, есть ли у этого обновления какие-либо проблемы? (извините мой частый случайный вход) 'update myTable set in_process = 'T', обработанный = 'T', где seq in (выберите отдельный (a.seq) из myTable a внутреннее соединение (выберите id из myTable, где status = 'N 'и обработано =' F ') b на a.id = b.id внутреннее соединение (выберите id из myTable, где status =' D 'и обработан =' F ') b на a.id = c.id , где a .procesed = 'F'; ' – Tom

+0

Трудно сказать, не опробовав, я не вижу никакой очевидной проблемы (в oracle, другие базы данных не позволяют использовать таблицу для обновления также в части из подзапросов. кроме обновлений, вам также придется удалить лишний кортеж, появившийся между прогонами, правильно? –

+0

Запрос работает нормально. Мне понадобилось его для покрытия этого конкретного случая или ему пришлось бы написать цикл в коде для его обработки. Другие случаи будут обрабатываться в коде, поскольку они необходимо вытащить ценности из контекста. Еще раз спасибо за ваше время и информацию об этом вместо триггеров. :) – Tom

Смежные вопросы