Модераторы: LSD

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Как сравнить данные в таблицах? 
:(
    Опции темы
Tigress
  Дата 20.7.2007, 09:51 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 10
Регистрация: 20.7.2007
Где: г. Краснодар

Репутация: нет
Всего: нет



Есть три сервера. В реплике. Реплика умирает (по 1000 битых транзакций на каждой ветке) smile ,  потому как должность админа вакантна  Буду останавливать базу и пытаться что-то сделать с этим. 

Нужен такой код, который будет сравнивать данные в таблицах на главном сервере с данными в таблицах двух других серверов. И если вдруг на главном сервере в таблице нет какой-то строки, которая есть в таблице на другом сервере (а таких случаев будет дофига), то добавлять ее (строку) в таблицу на главном серваке.

Помогите, пожалуйста с составлением кода. Идеи такие: 
Код

select a, b 
from T 
minus 
select a, b
from T@адрес_другого_сервера

Таблиц то дофига и больше...как бы это все оптимизировать (Ну и чтоб не три дня сравнивало, а хотяб за пару часов справилось)
Всем заранее большее СПАСИБО!
PM MAIL ICQ   Вверх
LSD
Дата 20.7.2007, 10:25 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Leprechaun Software Developer
****


Профиль
Группа: Модератор
Сообщений: 15718
Регистрация: 24.3.2004
Где: Dublin

Репутация: 18
Всего: 538



Есть сильное подозрение, что подобный селект на больших таблицах, приведет к "смерти" сервера. Я бы делал через курсоры, делаем два селекта, с сортировкой по первичному ключу и вперед.


--------------------
Disclaimer: this post contains explicit depictions of personal opinion. So, if it sounds sarcastic, don't take it seriously. If it sounds dangerous, do not try this at home or at all. And if it offends you, just don't read it.
PM MAIL WWW   Вверх
Tigress
Дата 20.7.2007, 10:40 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 10
Регистрация: 20.7.2007
Где: г. Краснодар

Репутация: нет
Всего: нет



LSD, в том то и дело, что боюсь, что всё умрет окончательно. Поэтому и спрашиваю совета. 
У меня таблиц (select count(*) from user_objects where user_objects.object_type='TABLE')  537 штук

То есть, кроме того, что нужно позаботится о быстроте сравнения пары таблиц, нужно еще и сделать так, чтобы автоматом перебирались все таблицы. Не в ручную же для каждой код вводить в самом деле. 

И это все дело должно отработать 2 раза! (сравнивать же с двумя базами)

>Я бы делал через курсоры, делаем два селекта, с сортировкой по первичному ключу и вперед.

А после курсора что? Построчно сравнивать? Ведь не совпадающие строки не обязательно в конце таблицы стоять будут (и не будут они там стоять сразу говорю)...
Можешь код набросать? а то чё то ИЯ БЛОНДИНКО  smile 







PM MAIL ICQ   Вверх
Sqlninja
Дата 20.7.2007, 11:21 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 353
Регистрация: 15.5.2006
Где: San Francisco, CA

Репутация: 13
Всего: 13



а че - репликация идет в режиме non-stop?
я бы сделал на удаленных серваках snapshot нужных таблиц, включил бы их в master refresh group. а на главном серваке обновляемые таблицы надо привязать к ней, и регулярно рефрешить.
Код

...
BEGIN
   DBMS_REFRESH.REFRESH ('&&_SCHEMA..&&_REP_GROUP.');
END;
/


короче стандартная репликация, только урезанная.


--------------------
It's better to burn out than to fade away.
PM MAIL WWW ICQ   Вверх
Tigress
Дата 20.7.2007, 11:36 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 10
Регистрация: 20.7.2007
Где: г. Краснодар

Репутация: нет
Всего: нет



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 
  )

Но боюсь...это будет неделю длится! Или я ошибаюсь? Помогиииите! Оптимизируйте решение, плз.

PM MAIL ICQ   Вверх
Sqlninja
Дата 20.7.2007, 11:51 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 353
Регистрация: 15.5.2006
Где: San Francisco, CA

Репутация: 13
Всего: 13



снимите битые транзакции вручную через Enterprise Manager Console. или пишите на email [email protected].


--------------------
It's better to burn out than to fade away.
PM MAIL WWW ICQ   Вверх
LSD
Дата 20.7.2007, 12:20 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Leprechaun Software Developer
****


Профиль
Группа: Модератор
Сообщений: 15718
Регистрация: 24.3.2004
Где: Dublin

Репутация: 18
Всего: 538



Цитата(Tigress @  20.7.2007,  11:40 Найти цитируемый пост)
А после курсора что? Построчно сравнивать? Ведь не совпадающие строки не обязательно в конце таблицы стоять будут (и не будут они там стоять сразу говорю)...

Бежишь сравниваешь PK обоих курсоров. 
- Если они равны, значит это одна и та же запись, далее сравниваешь поля.
- Если - не равны, значит эту запись надо добавить в ту БД PK которой больше.

Цитата(Tigress @  20.7.2007,  11:40 Найти цитируемый пост)
Можешь код набросать?

Сейчас нет времени, попытайся сам. Если не получится - пиши.


--------------------
Disclaimer: this post contains explicit depictions of personal opinion. So, if it sounds sarcastic, don't take it seriously. If it sounds dangerous, do not try this at home or at all. And if it offends you, just don't read it.
PM MAIL WWW   Вверх
Tigress
Дата 20.7.2007, 12:54 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 10
Регистрация: 20.7.2007
Где: г. Краснодар

Репутация: нет
Всего: нет



Как то так?
Код

cursor cur1 is 
select * from NameTable;

cursor cur2 is 
select * from NameTable@NameLink;

for rcur1 in cur1 loop
    for rcur2 in cur2 loop
    if rcur1.id=rcur2.id then begin F=True; Goto Metka end;
    end loop;
Metka:
 if F=true then begin insert into NameTable ... end;
 F=false;
end loop;

Так будет быстрее работать, чем при Minus?
И еще такой вопрос, как-то можно задать имя таблицы как переменную. Ну чтоб NameTable каждый раз не вручную править, а хотя бы чтоб это был параметр функции?
PM MAIL ICQ   Вверх
LSD
Дата 20.7.2007, 13:56 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Leprechaun Software Developer
****


Профиль
Группа: Модератор
Сообщений: 15718
Регистрация: 24.3.2004
Где: Dublin

Репутация: 18
Всего: 538



При использовании minus, у тебя все данные в таблице будут закачиваться в сервер. Если сервер это потянет, то работать будет даже быстрее. Но вот только я как-то сомневаюсь, что сервак способен это потянуть.


--------------------
Disclaimer: this post contains explicit depictions of personal opinion. So, if it sounds sarcastic, don't take it seriously. If it sounds dangerous, do not try this at home or at all. And if it offends you, just don't read it.
PM MAIL WWW   Вверх
Sherst
Дата 20.7.2007, 13:56 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 131
Регистрация: 26.10.2005

Репутация: нет
Всего: 2



Кайт говорил что если возможно использовать sql запросы то лучше использовать их.
PM MAIL   Вверх
Tigress
Дата 20.7.2007, 14:23 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 10
Регистрация: 20.7.2007
Где: г. Краснодар

Репутация: нет
Всего: нет



LSD, спасибо. Буду курсором. Примерно как написала. Потому как параллельно по ним бежать не удастся - ключи нельзя сравнить однозначно на больше-меньше (так чтоб точно знать в какую таблицу копировать).

А что скажете по поводу задания имени таблицы как параметра???


Sherst, да, Томас возможно так говорил...какие выводы?  smile  smile  smile 
PM MAIL ICQ   Вверх
DimW
Дата 23.7.2007, 08:04 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1330
Регистрация: 24.2.2005
Где: Орёл

Репутация: 23
Всего: 44



Цитата(Sherst @  20.7.2007,  13:56 Найти цитируемый пост)
Кайт говорил что если возможно использовать sql запросы то лучше использовать их. 


вот именно по этому делайте так:

Код

drop table table1
/
CREATE TABLE table1 AS SELECT * FROM table1@сервер1;
/


надо же слушаться дядю тома.
но этот пример, можно применить однажды - для того что бы данные во всех базах стали одинаковые.
а дальше курсорчиком.


Цитата(Tigress @  20.7.2007,  14:23 Найти цитируемый пост)
А что скажете по поводу задания имени таблицы как параметра???


поиск по - execute immediate

Это сообщение отредактировал(а) DimW - 23.7.2007, 11:54
PM MAIL ICQ   Вверх
Tigress
Дата 23.7.2007, 09:42 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 10
Регистрация: 20.7.2007
Где: г. Краснодар

Репутация: нет
Всего: нет



Попробую сделать так...
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;

нормально?
PM MAIL ICQ   Вверх
DimW
Дата 23.7.2007, 12:55 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1330
Регистрация: 24.2.2005
Где: Орёл

Репутация: 23
Всего: 44



Цитата(Tigress @  23.7.2007,  09:42 Найти цитируемый пост)
нормально? 


нет.


Цитата(Tigress @  23.7.2007,  09:42 Найти цитируемый пост)
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

на мой взгляд безполезные действия. да еще и не правельно написаны.
PM MAIL ICQ   Вверх
Tigress
Дата 23.7.2007, 13:15 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 10
Регистрация: 20.7.2007
Где: г. Краснодар

Репутация: нет
Всего: нет



Точно бесполезные...
Почему неправильно?
PM MAIL ICQ   Вверх
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Oracle"
Zloxa
LSD

Данный раздел предназначен для обсуждения проблем с Oracle Database, другие продукты Oracle здесь не обсуждаются. Просьба при создании темы, придерживаться следующих правил:

  • при создании темы давайте ей осмысленное название, описывающее суть проблемы
  • указывайте используемую версию базы, способ соединения и язык программирования
  • при ошибках обязательно приводите код ошибки и сообщение сервера
  • приводите код в котором возникла ошибка, по возможности дайте тестовый пример демонстрирующий ошибку
  • при вставке кода используйте соответсвующие теги: [code=sql] [/code] для подсветки SQL и PL/SQL кода, [code=java] [/code] - для Java, и т.д.

  • документация по Oracle: 9i, 10g, 11g
  • книги по Oracle можно поискать здесь
  • действия модераторов можно обсудить здесь

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Zloxa, LSD.

 
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Oracle | Следующая тема »


 




[ Время генерации скрипта: 0.1033 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.