Реплікація, синхронізація з двох баз, наприклад на Firebird, гетерогенні запити
Ми маємо одну прогу, зі з'єднаними базами, допустимо двома з різних IP. І тут натрапив на проблему. З Delphi не можу зробити запит порівняння двох таблиць із різних БД. Відписався на форуми, відповідь була сумною, не можливо чи складними шляхами, а хотів робити вже на знайдених прикладах. Ось питання на форумі.
Існують дві різні бази(з'єднання в одній програмі, на різні IP) через компоненти FIB(FIBDatabase) реалізація на Delphi. Потрібно порівняти дві таблиці по полях однакові структурою. Намагаюся зробити щось подібне до цього; ПРИКЛАДselect x1.fld from table x1 where not EXISTS(select x2.fld from table x2 where x2.fld=x1.fld ) - вибрати записи які не збігаються.
але з pfibdataset не можу вказати другу таблицю в іншій базі, назви таблиць збігаються. і не можу продовжити DM.efSDS.SelectSQL.Clear; DM.efSDS.SelectSQL.Add('SELECT X1.fld FROM X1 WHERE.');
На форумі бачив і це ПРИКЛАД:SELECT a.fld1, a.fld2 FROM db1.table1 a, db2.table1 b WHERE a. >, і це не мій як зробити.
Зрозуміло все, коли дві таблиці в одній базі. Як мені в коді запиту послаться на іншу таблицю в іншій базі (підключені до різних FIBDatabase, fibdataset) з таким же ім'ям, не можу зрозуміти як практично реалізувати це. І вивести як завгодно, припустимо DBGrid. Може хтось підкаже як на Delphi це реалізувати, приклади.
В основному отримав дві відповіді: 1. Якось через BDE 2. Що це гетерогенні запит , п..дец навіть не уявляю, що це, в Firebird не застосовний (хтось пише, може бути можливо в Firebird 3.0). Були відповіді переходу на платні бази та можливості робити гетерогенні запити у Oracle. Тут стало, зрозуміло, наткнувся на каміння, все не просто.
Була відповідь, робити два різні запити по кожній таблиці та порівнювати їх,майже строчно. Логічно виглядає приблизно так напевно
Мда, зі 100 записами все просто було, а база велика. Здається, глухий кут. І думки повертаються назад до ідеї на початку статті, окрема таблиця порівняння чи дод. поле. Всі ці складні замути та пошуку готового варіанта чи команд запиту, якісь перебори записів тощо. – все не підходить. І тут Інтернет НЕ ДОПОМОГ!. Буде робитися за принципом, думаю вийде швидко.
Особисте рішення, яке піде не тільки Firebird:
2. Для швидкого перенесення на базу А(основну), має бути місце куди ми записуємо якесь останню послідовну ID з баз B,C ми переносили. Згодом дані нові з'являються на базах B, C, ID збільшуються. Уточнюємо якісь останні зараз на B,С, на чому зупинилися на А, і докопуємо нові дані. Залишається проблема як розпізнавати різні бази B, С, хто є хто - це не проблема, просто створимо відмітні десь мітки в базі.
3. Виходить для обслуговування поле data_edit , фіксація останнього ID при переносі з інших баз B, C. Для надійності та ясності додаємо в базу А ще два поля у всі таблиці це ID першоджерела з інших баз (припустимо ID_primary) та поле мітки з якої бази доповнення (base_primary) ,
4. Залишається актуалізація бази А, коли нових записів, але наявністю редагування. Тут нам уже допоможуть поле data_edit, що ми створили і його швидке знаходження в іншій базі по полю ID_primary, а base_primary - вкаже ми тут господарювали. Маючи дати зміни, можна швидше стежити тільки за зміненими даними, а не ганяти всі бази від 1 запису до нескінченності.
Рішення здасться складним, але логічно дуже швидким при дохлому інтернеті у бази А. Залишається реалізувати це.
5. Створюємо програмулку або кнопочку, яка самазбирає назви таблиць, розставляє нові мітки, створює нові поля в обумовлені в пунктах 1-4 вище, не длубаючи все руками (в розробці).
INSERT INTO CURRENCY (ID, ISO_LAT, NAME, ISSHOW, HTMLCODE, RCODE) VALUES (840, 'USD', 'Долари США', 'Y', '$', 'R01235'); INSERT INTO CURRENCY (ID , ISO_LAT, NAME, ISSHOW, HTMLCODE, RCODE) VALUES (810, 'RUR', 'Рублі РФ', 'Y', 'р.', NULL);
З форуму порівняння та заміна MINUS
I має два еqual queries whit different filter applied onsame table. the first query returns (1,2,3,4,5) and the second returns (3,4,5).
I want apply the MINUS/EXCEPT operator: select1 minus select2 = (1,2)
How should I implements this logic using firebird SQL dialect ? (I'musing superserver v2.1)
I'm getting the opposite results performing select1 UNION select2 = (1,2,3,4,5)
У FB є не міно operator, so :
MINUS operator не існує в Firebird. closest approximation Я може думати, що деякий час, як example below. Це використовує спільні таблиці Expressions, які введені в Firebird 2.1, але можуть ходити в ході з суб'єктами (I just find CTE more readable)
У цьому питанні я використовую LEFT JOIN, щоб поєднати select1 і select2 , і потім тільки повернути ці рядки з select1, що не трапляється в select2
Потрібно поєднати запити. Наприклад, є запит сумарні покупки протягом дня, є запит сумарні продажу протягом дня. Потрібно, щоб у результуючому наборі були поля: дата, обсяг покупок, обсяг продажу. Як це зробити? На жаль, у Interbase немає конструкції типу select * from table1 left join (select * from table2).
1. select (select count(*) from table1), (select count(*) from table2) from rdb$database
Можна використовувати UNION якщо поля результуючихрекордсетів однакові
Можливо я не вірно зрозумів Ваше запитання, але якщо спробувати так:
Якщо щось не так то поясніть докладніше що Вам потрібно.
SELECT T1.ID, T2.ID FROM T1 FULL OUTER JOIN T2 ON (T2.
типу цього select t1.* from table1 t1 left join table2 t2 on t1. >where t2.id is null
select. from table1 where not exists(select. from table2 where. ) Піде ?
Це питання не закрите, редагується в міру реалізації питання.