Найти различия в строках между двумя таблицами в oracle 19

#sql #plsql #oracle19c

#sql #plsql #oracle19c

Вопрос:

Привет, ребята, у вас есть этот запрос: (oracle 19)

 CREATE TABLE  REGISTRO_LOCAL
   (    ID NUMBER, 
        USUARIO VARCHAR2(20), 
        FECHA_CARGA TIMESTAMP (6) DEFAULT CURRENT_TIMESTAMP, 
        fecha date,
        valor number(19,6),
        CONSTRAINT REGISTRO_LOCAL_PK PRIMARY KEY (ID) ENABLE
   );
   
CREATE SEQUENCE   REGISTRO_LOCAL_SEQ  MINVALUE 1 MAXVALUE 9999999999999999999999999999 INCREMENT BY 1 START WITH 41 CACHE 20 NOORDER  NOCYCLE;
commit;

ALTER TABLE REGISTRO_LOCAL 
MODIFY id DEFAULT REGISTRO_LOCAL_SEQ.nextval;



CREATE TABLE  REGISTRO_API
   (    ID NUMBER, 
        USUARIO VARCHAR2(20), 
        FECHA_CARGA TIMESTAMP (6) DEFAULT CURRENT_TIMESTAMP, 
        fecha date,
        valor number(19,6),
        CONSTRAINT REGISTRO_API_PK PRIMARY KEY (ID) ENABLE
   );
   
CREATE SEQUENCE   REGISTRO_API_SEQ  MINVALUE 1 MAXVALUE 9999999999999999999999999999 INCREMENT BY 1 START WITH 41 CACHE 20 NOORDER  NOCYCLE;
commit;

ALTER TABLE REGISTRO_API 
MODIFY id DEFAULT REGISTRO_API_SEQ.nextval;


Insert into REGISTRO_LOCAL (ID,USUARIO,FECHA_CARGA,FECHA,VALOR) values ('41','bird',to_timestamp('20/08/20 09:46:13,416616000','DD/MM/RR HH24:MI:SSXFF'),to_date('22/08/20','DD/MM/RR'),'23,234');
Insert into REGISTRO_LOCAL (ID,USUARIO,FECHA_CARGA,FECHA,VALOR) values ('42','dog',to_timestamp('20/08/20 09:46:13,488931000','DD/MM/RR HH24:MI:SSXFF'),to_date('21/08/20','DD/MM/RR'),'5,2341');
Insert into REGISTRO_LOCAL (ID,USUARIO,FECHA_CARGA,FECHA,VALOR) values ('43','horse',to_timestamp('20/08/20 09:46:31,436053000','DD/MM/RR HH24:MI:SSXFF'),to_date('23/08/20','DD/MM/RR'),'5');
Insert into REGISTRO_LOCAL (ID,USUARIO,FECHA_CARGA,FECHA,VALOR) values ('44','cat',to_timestamp('20/08/20 09:48:22,037646000','DD/MM/RR HH24:MI:SSXFF'),to_date('20/08/20','DD/MM/RR'),'67,234');
Insert into REGISTRO_LOCAL (ID,USUARIO,FECHA_CARGA,FECHA,VALOR) values ('45','zebra',to_timestamp('20/08/20 09:50:04,350761000','DD/MM/RR HH24:MI:SSXFF'),to_date('20/08/20','DD/MM/RR'),'23');
Insert into REGISTRO_LOCAL (ID,USUARIO,FECHA_CARGA,FECHA,VALOR) values ('46','spider',to_timestamp('20/08/20 09:50:49,557596000','DD/MM/RR HH24:MI:SSXFF'),to_date('22/08/20','DD/MM/RR'),'4');

Insert into REGISTRO_API (ID,USUARIO,FECHA_CARGA,FECHA,VALOR) values ('80','bird',to_timestamp('20/08/20 09:46:13,416616000','DD/MM/RR HH24:MI:SSXFF'),to_date('22/08/20','DD/MM/RR'),'23,234');
Insert into REGISTRO_API (ID,USUARIO,FECHA_CARGA,FECHA,VALOR) values ('81','horse',to_timestamp('20/08/20 09:46:31,436053000','DD/MM/RR HH24:MI:SSXFF'),to_date('23/08/20','DD/MM/RR'),'8');
Insert into REGISTRO_API (ID,USUARIO,FECHA_CARGA,FECHA,VALOR) values ('82','cat',to_timestamp('20/08/20 09:48:22,037646000','DD/MM/RR HH24:MI:SSXFF'),to_date('21/08/20','DD/MM/RR'),'6,234');
Insert into REGISTRO_API (ID,USUARIO,FECHA_CARGA,FECHA,VALOR) values ('83','spider',to_timestamp('20/08/20 09:50:49,557596000','DD/MM/RR HH24:MI:SSXFF'),to_date('22/08/20','DD/MM/RR'),'4');
Insert into REGISTRO_API (ID,USUARIO,FECHA_CARGA,FECHA,VALOR) values ('84','rabbit',to_timestamp('20/08/20 09:50:49,618559000','DD/MM/RR HH24:MI:SSXFF'),to_date('22/08/20','DD/MM/RR'),'3,867');
  

И используя этот образ:

введите описание изображения здесь

Я хотел бы знать, есть ли способ определить различия между двумя таблицами.

Данные, содержащие последнюю информацию, будут в таблице REGISTRO_API. Будет легко удалить REGISTRO_LOCAL и вставить дату из REGISTRO_API.

Но мой я не могу этого сделать.

1— Я должен выполнить обновления через REGISTRO_LOCAL с новой датой из REGISTRO_API (это может быть удаление и создание, необязательно ОБНОВЛЕНИЕ)

2— Я должен удалить запись из REGISTRO_LOCAL, когда эта запись не существует в REGISTRO_API

3— Я должен вставить запись, которая существует в REGISTRO_API и отсутствует в REGISTRO_LOCAL

Итак, какой лучший способ сделать это?

Комментарии:

1. Все это может быть обработано триггером в REGISTRO_API, который при создании также создает строку в LOCAL, при обновлении он находит эту строку и обновляет ее. И при удалении эта строка также удаляется.

2. здравствуйте, но проблема в том, что у LOCAL есть данные, а API — это процесс, который вставляет все записи при ночном чтении из rest api. Моя работа сейчас заключается в получении различий и выполнении трех мыслей, которые я должен выполнить.

3. Тогда вам нужно запланированное задание, которое выполняется после заполнения API каждую ночь. Это просто просматривает каждую строку в LOCAL и проверяет ее на соответствие API, если она есть, но отличается, обновите ее. Если его там нет, удалите его. Затем также просмотрите таблицу API, чтобы проверить, нет ли записей в LOCAL, и создайте их.

Ответ №1:

Если я понимаю ваши требования, вы можете идентифицировать все строки, используя «Полное внешнее соединение»:

 select rl.id           rl_id
     , rl.usuario      rl_usuario
     , rl.fecha_carga  rl_fecha_carga
     , rl.fecha        rl_fecha
     , rl.valor        rl_valor
     , ra.id           ra_id
     , ra.usuario      ra_usuario
     , ra.fecha_carga  ra_fecha_carga
     , ra.fecha        ra_fecha
     , ra.valor        ra_valor 
  from registro_local rl
  full outer join registro_api ra
     on ra.usuario = rl.usuario ; 
  

Используйте это как основу для процедуры для выполнения обновлений. Определите курсор для приведенного выше запроса, они используют массовую сборку и Forall для выполнения вставок как в локальные таблицы, так и в таблицы API. Затем выполните итерацию коллекции, удаляя те элементы, которые были вставлены или не были обновлены. В зависимости от объема данных вы можете захотеть проверить «не обновлено» в самом запросе. Наконец, снова используйте Forall для обработки обновлений в local, см. fiddle для полного примера. Затем вы можете использовать свой планировщик заданий, будь то внутренний или внешний планировщик Oracle, для запуска процедуры по мере необходимости.

Ответ №2:

я решаю это таким образом:

Первый — я выполняю слияние между двумя таблицами, Второй — обновление ЛОКАЛЬНОЙ ТАБЛИЦЫ

И вот как это выглядит:

введите описание изображения здесь

Запрос:

 merge into REGISTRO_LOCAL l
using
    (
        select USUARIO
              ,FECHA_CARGA
              ,FECHA
              ,VALOR
        from REGISTRO_API
    ) a
on (
    1=1
    and l.USUARIO = a.USUARIO
    and l.FECHA_CARGA = a.FECHA_CARGA
    and l.FECHA = a.FECHA
    --and l.VAlOR = a.VALOR
    )
WHEN MATCHED THEN
    update set l.VAlOR = a.VALOR
              ,l.ACTION = 'U'
WHEN NOT MATCHED THEN
    insert (
         USUARIO
        ,FECHA_CARGA
        ,FECHA
        ,VALOR
        ,ACTION
    )values(
         a.USUARIO
        ,a.FECHA_CARGA
        ,a.FECHA
        ,a.VALOR
        ,'I'
    );
END;

update REGISTRO_LOCAL
set action = 'D'
where action is null;
commit;
  

я надеюсь, что это может быть полезно для кого-то еще…

С уважением