2015-03-29 3 views
1

Буду признателен за всю помощь, которую я могу получить. Я учусь PL/SQL и наткнулся на проблему так, пожалуйста, помогите мне найти подходящий способ обработки этой ситуации :) Я бегу Oracle 11gR2PL/SQL insert на основе условий

Моя схема:

CREATE TABLE "ENTRY" 
(
"TYPE" VARCHAR2(5 CHAR) , 
"TRANSACTION" VARCHAR2(5 CHAR), 
"OWNER" VARCHAR2(5 CHAR) 
); 

CREATE TABLE "VIEW" 
(
"TYPE" VARCHAR2(5 CHAR) , 
"TRANSACTION" VARCHAR2(5 CHAR), 
"OWNER" VARCHAR2(5 CHAR) 
); 

CREATE TABLE "REJECTED" 
(
"TYPE" VARCHAR2(5 CHAR) , 
"TRANSACTION" VARCHAR2(5 CHAR), 
"OWNER" VARCHAR2(5 CHAR) 
); 

Мой образец данные:

insert into entry (type, transaction, owner) values (11111, 11111, 11111); 
insert into entry (type, transaction, owner) values (22222, 22222, 22222); 

Теперь для загадочных частей, я написал эту процедуру, которая должна копировать значения из таблицы элемента, чтобы просмотреть таблицу, если запись не существует для конкретной сделки (и владелец) комбинации. Если такая комбинация существует в таблице VIEW, запись должна затем перейти в таблицу REJECTED. Эта процедура делает это, но при нескольких прогонах процедуры я получаю все больше записей в таблице REJECTED, поэтому мой вопрос заключается в том, как ограничить вставки в таблице REJECTED - если запись уже существует в таблице REJECTED, ничего не делайте.

create or replace PROCEDURE COPY AS   

v_owner_entry ENTRY.owner%TYPE; 
v_transaction_entry ENTRY.transaction%TYPE; 

v_owner VIEW.owner%TYPE; 
v_transaction VIEW.transaction%TYPE; 

begin 

begin 

select e.owner, e.transaction, v.owner, v.transaction 
into v_owner_entry, v_transaction_entry, v_owner, v_transaction 
from entry e, view v 
where e.owner = v.owner 
and e.transaction = v.transaction; 

EXCEPTION 
when too_many_rows 
then 
    insert into REJECTED 
    (
    TYPE, 
TRANSACTION, 
OWNER 
) 
    SELECT 
    s1.TYPE, 
    s1.TRANSACTION, 
    s1.OWNER 
    FROM ENTRY s1; 


when no_data_found 
THEN 

insert into VIEW 
    (
     TYPE, 
    TRANSACTION, 
    OWNER 
    ) 
    SELECT 
     s.TYPE, 
    s.TRANSACTION, 
    s.OWNER 
     FROM ENTRY s; 

end; 
end; 

Любые предложения ребята? :)

Cheers!

UPDATE Извините, если исходное сообщение не было достаточно ясно - Процедура должна реплицировать данные (на ежедневной основе) из DB1 в DB2 и вставить в VIEW или отвергаются в зависимости от условий. Вот фото, может быть, это будет понятнее: enter image description here

ответ

2

Я думаю, что Дмитрий пытался использовать MERGE в случае too_many_rows вашего обработчика исключений. Итак, вы уже сделали SELECT спереди и определили, что строка Entry появится в вашей таблице View, и поэтому она вызывает исключение too_many_rows.

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

Как программист подмастерья, вместо того чтобы пытаться придумать что-то ужасно изящное, я бы использовал более грубую силу.

Что-то подобное:

BEGIN 
    FOR entry_cur IN 
     (select e.owner, e.transaction, SUM(NVL2(v.owner, 1, 0)) rec_count 
      from entry e, view v 
      where e.owner = v.owner(+) 
      and e.transaction = v.transaction(+) 
     GROUP BY e.owner, e.transaction) 
    LOOP 
     CASE WHEN rec_count > 0 
      THEN INSERT INTO view 
      ELSE MERGE INTO rejected r 
        ON (r.transaction = entry_cur.transaction 
        AND r.owner = entry_cur.owner) 
        WHEN NOT MATCHED THEN INSERT blah blah blah 
     ; 
    END LOOP; 
END; 

HAVING COUNT (*)> 1 будет не выброшенные исключения. Цикл дает вам правильную запись, которую вы не хотите вставлять в View. BTW, я не мог понять, что вы использовали ключевые слова для имен объектов - просмотр, транзакция и т. Д. Вы указали имена таблиц в инструкции CREATE TABLE «VIEW», которая охватывает тот факт, что это ключевые слова, t, когда вы ссылались на них позже, поэтому я удивлен, что компилятор не отклонил код. Я думаю, что это рецепт катастрофы, потому что это делает отладки намного сложнее. Я просто надеюсь, что вы сделали это для примера здесь, а не в PL/SQL.

Лично мне не удалось использовать оператор MERGE, где он не работал последовательно, но это был Oracle версия давно и, вероятно, мое собственное незнание в том, как это должно работать.

+0

Привет, Stew! Во-первых, я видел свою ошибку с именами таблиц в моем коде, это называется VIEWER, а не VIEW и т. Д. ... Я проверю его, как только я вернусь домой! – user3782821

+0

Отлично. Если это сработает, я буду благодарен за голосование, поскольку я мог бы использовать очки. – StewS2

1

Используйте MERGE заявление:

merge into REJECTED r 
using ENTRY e 
    on (r.type = e.type and 
     r.transaction = e.transaction and 
     r.owner = e.owner) 
when not matched then insert (type, transaction, owner) 
values (e.type, e.transaction, e.owner) 

Этот запрос будет вставить в таблицу REJECTED только комбинации (type, transaction, owner) из таблицы ENTRY, которые еще нет.

+0

Спасибо за быстрый ответ! :) Я попробую и опубликую результаты, но процедура должна вставлять данные только в таблицу REJECTED, если эта же строка уже присутствующий в таблице VIEW, что-то вроде: , если строка с комбинацией транзакций и владельца отсутствует в таблице VIEW, вставьте ее там (из таблицы ENTRY), если она присутствует в таблице VIEW, вставьте ее в таблицу REJECTED (извините, если Я не был достаточно ясен) – user3782821

+0

@ user3782821 Без проблем м. Как работает «MERGE» (в двух словах): предложение «merge into» - имя таблицы, в которую вы хотите поместить свои данные; предложение 'using' - источник данных, это может быть имя таблицы или запрос' select'; clause 'on' - список условий для сравнения данных в источнике и в пункте назначения; поэтому, если вам нужны данные, которые присутствуют в таблице 'view', вам нужно заменить таблицу' entry' на sql-запрос, который выбирает нужные строки. Вы можете легко сделать это сами. – Dmitry

+0

Спасибо за ваше время и терпение. Дмитрий, я протестировал слияние, но мне это не подходит. Я добавил фотографию процесса, возможно, это было бы яснее. Еще раз спасибо за ответ! – user3782821

1

Вы пытаетесь закодировать себя из затруднительного положения, в которое вы вдумались.

Таблица должна содержать ваше лицо. Не должно быть таблицы сущностей в одном состоянии, другой таблицы для объектов в другом состоянии и еще одной таблицы для объектов в другом состоянии. Вы видите проблемы, к которым это может привести.

Состояние может быть атрибутом (полем или столбцом) одной таблицы. Или нормализуется к таблице state, но все же только одна таблица сущностей. Когда объект изменяет состояния, это выполняется обновлением, а не перемещением из одной таблицы в другую.

+0

Я добавил обновление, поэтому, возможно, это поможет. Спасибо за ваше время! – user3782821

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