1 Востаннє редагувалося Konstantin78 (13.06.2018 19:21:07)

Тема: Питання по "merge", мови sql

Добрий час, форумчане.

Є таблиця пристроїв (DEVICE) у БД на FireBird (з полями "Найменування", "Тип", "Зав.номер" і так далі) в яку з Excel експортуються дані (пристрої).

У БД додалася друга таблиця "Человеко/години" (NORM_HOURS), в якій треба містити тільки поля "Найменування" і "Тип" цих пристроїв ну і ще деякі поля відмінні від полів в DEVICE.

Т.е. у NORM_HOURS повинні міститися тільки унікальні пристрої по обумовлених двох полях.

Після експорту пристроїв з файлу в DEVICE, я роблю операцію "MERGE", для таблиці NORM_HOURS, щоб ці пристрої з'явилися в NORM_HOURS.

merge into NORM_HOURS nh using DEVICES d on((nh.NAME_DEVICE=d.NAME_DEVICE and nh.TYPE_DEVICE=d.TYPE_DEVICE))
when matched then
update set nh.NAME_DEVICE=d.NAME_DEVICE, nh.TYPE_DEVICE=d.TYPE_DEVICE
when not matched then
insert(nh.ID, nh.NAME_DEVICE, nh.TYPE_DEVICE, nh.USER_ID, nh.DEPARTMENT_ID, nh.TYPE_INPUT)
values(GEN_ID(GEN_ID_NORM_HOURS, 1), d.NAME_DEVICE, d.TYPE_DEVICE, 1, 2, 3)

Питання по цій темі:

1. чи можна провести операцію "MERGE" робити не для усієї таблиці DEVICE, а тільки для деяких її рядків, скажемо в яких d.PROPOSAL _ ID=7 наприклад?

2. якщо раптом у мене d.TYPE_DEVICE порожньо, а d.NAME_DEVICE заповнене, то такі рядки продовжують вставлятися, при повторному проведенні скрипта(не дивлячись на те, що вони в NORM_HOURS вже є), чи можна як-небудь позбавитися від повторної вставки?

3. і чи правильно буде якщо я із скрипта приберу рядки:

...when matched then update set nh.NAME_DEVICE=d.NAME_DEVICE, nh.TYPE _ DEVICE=d.TYPE_DEVICE

? Просто я НЕ хочу оновлювати ті рядки в NORM_HOURS, які вже в ній є

Заздалегідь спасибі за відповідь

2

Re: Питання по "merge", мови sql

0. Почитайте щось по SQL і нормальних формах.
1. Так.

when matched AND (умова) then ...
when not matched AND (умова) then ...

2. "Порожньо" - я так розумію, це NULL. Результат практично будь-якої операції із NULL - це NULL; зокрема і операцій = та AND, тому (nh.NAME_DEVICE=d.NAME_DEVICE and nh.TYPE_DEVICE=d.TYPE_DEVICE) теж матиме значення NULL і спрацює гілка NOT MATCHED. На щастя, в FireBird 2.0 і вище є оператор DISTINCT:

(nh.NAME_DEVICE IS NOT DISTINCT FROM d.NAME_DEVICE and nh.TYPE_DEVICE IS NOT DISTINCT FROM d.TYPE_DEVICE)

В старших версіях треба було писати

nh.NAME_DEVICE=d.NAME_DEVICE OR (nh.NAME_DEVICE IS NULL AND d.NAME_DEVICE IS NULL) ...

https://www.firebirdsql.org/pdfmanual/h … sting.html
3. Якщо вам потрібна лише одна гілка MATCH, має сенс скористатися простим запитом - INSERT, UPDATE, UPDATE OR INSERT INTO, DELETE.
4. форумчани, людино-години, т.ч. (таким чином).

Декалог програміста-початківця: https://replace.org.ua/post/132988/
Подякували: leofun011

3 Востаннє редагувалося Konstantin78 (13.06.2018 22:09:47)

Re: Питання по "merge", мови sql

koala написав:

.

when matched AND (умова) then ...
when not matched AND (умова) then ...

Я вже пробував:

...when matched and (d.PROPOSAL_ID=7) then...

На жаль, цей рядок видає помилку:
Invalid token.
Dynamic SQL Error.
SQL error code = -104.
Token unknown - line 3, column 17.
and.

P.S.
- FireBird2.5

Подякували: leofun011

4

Re: Питання по "merge", мови sql

Так, схоже, в FireBird додаткові умови не підтримуються.
https://www.firebirdsql.org/file/docume … -tbl-merge
Тоді

using (SELECT * FROM DEVICES WHERE умова) d
Декалог програміста-початківця: https://replace.org.ua/post/132988/
Подякували: Konstantin78, leofun01, PRY3