Это ваш пример данных и способ извлечь аббревиатуру . Эта опция предполагает, что это последнее «слово» (\w+$
) в адресе. Если он находится в другом месте, вы получите неправильный результат.
SQL> with test (name, address_l1) as
2 (select 'Tom', '330 Darrow Street' from dual union all
3 select 'John', '40 Pine CT' from dual union all
4 select 'Smith', '110 Varady ave' from dual
5 )
6 select t.name,
7 t.address_l1,
8 regexp_substr(t.address_l1, '\w+$') abbrev
9 from test t;
NAME ADDRESS_L1 ABBREV
----- ----------------- ----------
Tom 330 Darrow Street Street
John 40 Pine CT CT
Smith 110 Varady ave ave
SQL>
Теперь, объедините извлеченную аббревиатуру с другой таблицей, чтобы получить ее полную форму. Поскольку неизвестно, будет ли кто-то вводить «CT», «Ct» или «ct», я использовал функцию lower
, чтобы сопоставить эти значения. Внешнее объединение используется для несуществующих сокращений:
SQL> with
2 test (name, address_l1) as
3 (select 'Tom', '330 Darrow Street' from dual union all
4 select 'John', '40 Pine CT' from dual union all
5 select 'Smith', '110 Varady ave' from dual
6 ),
7 abbrev (abbreviation, full_Form) as
8 (select 'St', 'Street' from dual union all
9 select 'Ave', 'Avenue' from dual union all
10 select 'Dr', 'Drive' from dual union all
11 select 'Ct', 'Court' from dual
12 )
13 select t.name,
14 t.address_l1,
15 regexp_substr(t.address_l1, '\w+$') abbrev,
16 a.full_form
17 from test t left join abbrev a on
18 lower(a.abbreviation) = lower(regexp_substr(t.address_l1, '\w+$'));
NAME ADDRESS_L1 ABBREV FULL_F
----- ----------------- ---------- ------
Smith 110 Varady ave ave Avenue
John 40 Pine CT CT Court
Tom 330 Darrow Street Street
SQL>
Наконец, замените сокращения полными формами (см. Комментарии в коде):
SQL> with
2 test (name, address_l1) as
3 (select 'Tom', '330 Darrow Street' from dual union all
4 select 'John', '40 Pine CT' from dual union all
5 select 'Smith', '110 Varady ave' from dual
6 ),
7 abbrev (abbreviation, full_Form) as
8 (select 'St', 'Street' from dual union all
9 select 'Ave', 'Avenue' from dual union all
10 select 'Dr', 'Drive' from dual union all
11 select 'Ct', 'Court' from dual
12 )
13 select t.name,
14 t.address_l1,
15 -- abbreviation:
16 -- regexp_substr(t.address_l1, '\w+$') abbrev,
17 -- its full form:
18 -- a.full_form,
19 --
20 -- position of the last space character in address string
21 -- regexp_instr(t.address_l1, '[^ ]+', 1, regexp_count(t.address_l1, ' ') + 1) i,
22 --
23 -- concatenate the first part of the address (without the "abbreviation" ...
24 substr(t.address_l1,
25 1,
26 regexp_instr(t.address_l1, '[^ ]+', 1, regexp_count(t.address_l1, ' ') + 1) - 1
27 )
28 ||
29 -- ... with its full form if it exists. If not, use what you have
30 -- (this option covers the "Street" example in your test case)
31 nvl(a.full_form, regexp_substr(t.address_l1, '\w+$')) result
32 from test t left join abbrev a on
33 lower(a.abbreviation) = lower(regexp_substr(t.address_l1, '\w+$'));
NAME ADDRESS_L1 RESULT
----- ----------------- ---------------------------------------------------------------------------
----------
Smith 110 Varady ave 110 Varady Avenue
John 40 Pine CT 40 Pine Court
Tom 330 Darrow Street 330 Darrow Street
SQL>
Это первое часть истории. Обратите внимание, что это работает для образцов данных; если он изменится или не соответствует тому, что вы опубликовали, этот код необходимо будет скорректировать (например, удалить лишние пробелы).
По состоянию на:
нам нужно создать оператор вставки / обновления
- , который будет оператором
MERGE
; проще в использовании, чем отдельно UPDATE
+ INSERT
Например:
SQL> merge into test t
2 using (select t.name,
3 substr(t.address_l1,
4 1,
5 regexp_instr(t.address_l1, '[^ ]+', 1, regexp_count(t.address_l1, ' ') + 1) - 1
6 )
7 ||
8 nvl(a.full_form, regexp_substr(t.address_l1, '\w+$')) result
9 from test t left join abbrev a on
10 lower(a.abbreviation) = lower(regexp_substr(t.address_l1, '\w+$'))
11 ) x
12 on (t.name = x.name)
13 when matched then update set
14 t.result = x.result
15 when not matched then insert (name, result)
16 values (x.name, x.result);
3 rows merged.
SQL> select * From test;
NAME ADDRESS_L1 RESULT
---------- ------------------------------ ----------------------------------------
Tom 330 Darrow Street 330 Darrow Street
John 40 Pine CT 40 Pine Court
Smith 110 Varady ave 110 Varady Avenue
SQL>
мы должны делать это ежедневно
- использует планировщик, то есть встроенный пакет
DBMS_SCHEDULER
(или DBMS_JOB
). Чтобы использовать его, поместите ваш код в хранимую процедуру, которая затем будет вызываться этой утилитой.
В самом простом варианте вы поместите приведенный выше оператор слияния в процедуру as is :
create or replace procedure p_merge as
begin
merge into test ...
end;
/
Запланируйте его запуск каждый день в полдень:
SQL> declare
2 l_job number;
3 begin
4 dbms_Job.submit(l_job,
5 'p_merge;',
6 sysdate,
7 'trunc(sysdate) + 12/24'
8 );
9 commit;
10 end;
11 /
PL/SQL procedure successfully completed.
SQL>
Все, более или менее.