| Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
| Форум программистов > Oracle > Как сравнить данные в таблицах? |
| Автор: Tigress 20.7.2007, 09:51 | ||
| Есть три сервера. В реплике. Реплика умирает (по 1000 битых транзакций на каждой ветке) Нужен такой код, который будет сравнивать данные в таблицах на главном сервере с данными в таблицах двух других серверов. И если вдруг на главном сервере в таблице нет какой-то строки, которая есть в таблице на другом сервере (а таких случаев будет дофига), то добавлять ее (строку) в таблицу на главном серваке. Помогите, пожалуйста с составлением кода. Идеи такие:
Таблиц то дофига и больше...как бы это все оптимизировать (Ну и чтоб не три дня сравнивало, а хотяб за пару часов справилось) Всем заранее большее СПАСИБО! |
| Автор: LSD 20.7.2007, 10:25 |
| Есть сильное подозрение, что подобный селект на больших таблицах, приведет к "смерти" сервера. Я бы делал через курсоры, делаем два селекта, с сортировкой по первичному ключу и вперед. |
| Автор: Tigress 20.7.2007, 10:40 |
| LSD, в том то и дело, что боюсь, что всё умрет окончательно. Поэтому и спрашиваю совета. У меня таблиц (select count(*) from user_objects where user_objects.object_type='TABLE') 537 штук То есть, кроме того, что нужно позаботится о быстроте сравнения пары таблиц, нужно еще и сделать так, чтобы автоматом перебирались все таблицы. Не в ручную же для каждой код вводить в самом деле. И это все дело должно отработать 2 раза! (сравнивать же с двумя базами) >Я бы делал через курсоры, делаем два селекта, с сортировкой по первичному ключу и вперед. А после курсора что? Построчно сравнивать? Ведь не совпадающие строки не обязательно в конце таблицы стоять будут (и не будут они там стоять сразу говорю)... Можешь код набросать? а то чё то ИЯ БЛОНДИНКО |
| Автор: Sqlninja 20.7.2007, 11:21 | ||
| а че - репликация идет в режиме non-stop? я бы сделал на удаленных серваках snapshot нужных таблиц, включил бы их в master refresh group. а на главном серваке обновляемые таблицы надо привязать к ней, и регулярно рефрешить.
короче стандартная репликация, только урезанная. |
| Автор: Tigress 20.7.2007, 11:36 |
| Sqlninja, наверно ж нон стоп. Вернее, там уже пару месяцев ВСЕ ПЛОХО!!! Из за количества битых транзакций - база практически стоит... Задача начальством поставлена такая.. 1. Остановить базу, у нас собрать в талицы все данные, которых нет, но они есть в таблицах на других серваках. 2. Похерить все данные таблиц на тех серваках 3. И залить их туда заново... Я не админ нифига... Я б так: сделала б курсор по всем таблицам cursor cur is select object_name as NameTable from user_objects where user_objects.object_type='TABLE' order by object_name а потом по каждой строке в курсоре for rcur in cur loop (не знаю тока можно ли так имя передать): insert into NameTable ( select * from rcur.NameTable@NameLink minus select * from rcur.NameTable ) Но боюсь...это будет неделю длится! Или я ошибаюсь? Помогиииите! Оптимизируйте решение, плз. |
| Автор: Sqlninja 20.7.2007, 11:51 |
| снимите битые транзакции вручную через Enterprise Manager Console. или пишите на email [email protected]. |
| Автор: Tigress 20.7.2007, 12:54 | ||
Как то так?
Так будет быстрее работать, чем при Minus? И еще такой вопрос, как-то можно задать имя таблицы как переменную. Ну чтоб NameTable каждый раз не вручную править, а хотя бы чтоб это был параметр функции? |
| Автор: LSD 20.7.2007, 13:56 |
| При использовании minus, у тебя все данные в таблице будут закачиваться в сервер. Если сервер это потянет, то работать будет даже быстрее. Но вот только я как-то сомневаюсь, что сервак способен это потянуть. |
| Автор: Sherst 20.7.2007, 13:56 |
| Кайт говорил что если возможно использовать sql запросы то лучше использовать их. |
| Автор: Tigress 20.7.2007, 14:23 |
| LSD, спасибо. Буду курсором. Примерно как написала. Потому как параллельно по ним бежать не удастся - ключи нельзя сравнить однозначно на больше-меньше (так чтоб точно знать в какую таблицу копировать). А что скажете по поводу задания имени таблицы как параметра??? Sherst, да, Томас возможно так говорил...какие выводы? |
| Автор: DimW 23.7.2007, 08:04 | ||||
вот именно по этому делайте так:
надо же слушаться дядю тома. но этот пример, можно применить однажды - для того что бы данные во всех базах стали одинаковые. а дальше курсорчиком. поиск по - execute immediate |
| Автор: Tigress 23.7.2007, 09:42 |
| Попробую сделать так... CREATE OR REPLACE PROCEDURE Update_Tables(NameLink in varchar2) is NameTable varchar(50); NameTable_with_Link varchar(100); Rec_Count_in_Table integer; Rec_Count_in_Table_with_Link integer; cursor CUR is select table_name from user_tables; BEGIN FOR r IN CUR LOOP NameTable=r.table_name; NameTable_with_Link=NameTable+'@'+NameLink; execute immediate 'select count(*) into Rec_Count_in_Table from' || NameTable; execute immediate 'select count(*) into Rec_Count_in_Table_with_Link from' || NameTable_with_Link; if Rec_Count_in_Table_with_Link<>Rec_Count_in_Table then execute immediate 'insert into'|| NameTable || '( select * from ' || NameTable_with_Link ||' minus select * from ' || NameTable ||' )'; end if; End Loop; END; нормально? |
| Автор: DimW 23.7.2007, 12:55 | ||
нет.
на мой взгляд безполезные действия. да еще и не правельно написаны. |
| Автор: Tigress 23.7.2007, 13:15 |
| Точно бесполезные... Почему неправильно? |
| Автор: DimW 23.7.2007, 13:24 | ||||
потому что так:
в переменную Rec_Count_in_Table ни чего не запишешь. а вот так да:
|