Pl sql Pro c или оператор обновления для исправления адреса от сокращения до полной формы - PullRequest
0 голосов
/ 22 февраля 2020

у нас есть 2 таблицы employee и address_check в базе данных oracle. у нас есть сценарий, в котором нам нужно проверить, не является ли адрес человека не полной формой в столбцах адресов, и нам нужно проверить другую таблицу на наличие аббревиатуры и full_forms, чтобы заменить сокращение на full_forms. мы должны делать это на ежедневной основе для новых сотрудников. Таким образом, нам нужен оператор обновления или вставки для этого значения копии столбца address_l1 в address_l1_ c с full_form.

нам необходимо создать оператор вставки / обновления или процедуру pl sql, где он должен проверять столбцы адресов людей и узнайте, присутствуют ли какие-либо сокращения и присутствуют ли сокращения. Следует проверить, что сокращение присутствует в таблице address_check, найти его полную форму, получить эту полную форму и заменить ее в примере address_l1_ c.

и данных примера, как показано ниже:

enter image description here

1 Ответ

0 голосов
/ 22 февраля 2020

Это ваш пример данных и способ извлечь аббревиатуру . Эта опция предполагает, что это последнее «слово» (\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>

Все, более или менее.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...