Отслеживание изменения данных на Oracle 9 без отметок времени и индексации - PullRequest
0 голосов
/ 06 августа 2020

Мы создаем хранилище данных на BigQuery, которое включает в себя данные из старой транзакционной базы данных Oracle 9 (все еще активной), которая не включает никакой индексации или временных меток.

Использование Standard SQL , Я хотел бы проанализировать изменения в некоторых таблицах, импортированных из этой базы данных.

Упрощая ситуацию, представьте, что у нас есть две версии одной и той же таблицы before и after следующим образом:

with before as (
    select 
    'U123' as user, 'Gum' as product, '3' as quantity 
    union all 
    select 
    'U456', 'Tissue', '20'
    union all
    select
    'U123', 'Cream', '1'
    )

и

with after as (
    select 
    'U123' as user, 'Gum' as product, '3' as quantity 
    union all 
    select 
    'U456', 'Tissue', '20'
    union all
    select
    'U123', 'Cream', '3'
    union all
    select
    'U456', 'Tomato', '5'
    )

Итак, строка 4 была добавлена, а строка 3 изменена.

Каков правильный подход к сравнению данных и обнаружению изменений при отсутствии индексации и временных меток?

Итак, сравнительный метод должен вывести:

user | product | quantity
U123 | Cream   | 3
U456 | Tomato  | 5

Я даже не знаю, с чего начать.

Ответы [ 2 ]

1 голос
/ 06 августа 2020

Oracle 9 отслеживает изменение данных на уровне строки с помощью SCN (System Change Number). В результате любое изменение, выполненное с помощью DML (INSERT / UPDATE), внутренне фиксируется с помощью TIMESTAMP.

Как это работает?

  1. Создание таблицы с опцией ROWDEPENDENCIES
  2. Используйте функцию SCN_TO_TIMESTAMP (ORA_ROWSCN), чтобы получить TIMETAMP изменений строки

Пример:

-- Create Table
CREATE TABLE SCNTEST(USER NUMBER, PRODUCT NUMBER, QUANTITY NUMBER) ROWDEPENDENCIES;

-- Insert Data
INSERT ...
    
-- Query Data
SELECT USER, PRODUCT, QUANTITY, SCN_TO_TIMESTAMP(ORA_ROWSCN) FROM SCNTEST;

Вы можете сгруппировать данные по значению SCN_TO_TIMESTAMP(ORA_ROWSCN), чтобы получить записи до и после.

1 голос
/ 06 августа 2020

Ниже приведено значение для BigQuery Standard SQL

#standardSQL
SELECT user, product, IFNULL(a.quantity, 0) - IFNULL(b.quantity, 0) AS quantity
FROM after a
FULL OUTER JOIN before b
USING(user, product)
WHERE IFNULL(a.quantity, 0) != IFNULL(b.quantity, 0)

При применении к образцам данных из вашего вопроса, как в примере ниже

#standardSQL
WITH before AS (
  SELECT 'U123' AS user, 'Gum' AS product, 3 AS quantity UNION ALL 
  SELECT 'U456', 'Tissue', 20 UNION ALL
  SELECT 'U123', 'Cream', 1
), after AS (
  SELECT 'U123' AS user, 'Gum' AS product, 3 AS quantity UNION ALL 
  SELECT 'U456', 'Tissue', 20 UNION ALL
  SELECT 'U123', 'Cream', 3 UNION ALL
  SELECT 'U456', 'Tomato', 5
)
SELECT user, product, IFNULL(a.quantity, 0) - IFNULL(b.quantity, 0) AS quantity
FROM after a
FULL OUTER JOIN before b
USING(user, product)
WHERE IFNULL(a.quantity, 0) != IFNULL(b.quantity, 0)  

, вывод будет

Row user    product quantity     
1   U123    Cream   2    
2   U456    Tomato  5       
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...