Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Oracle Новый топик    Ответить
 Дублирование записей  [new]
Burya_
Member

Откуда:
Сообщений: 56
Все привет!
Не подскажите каким образои лучше всего проверить таблицу на дублирование записей
Смысл такой есть запрос, который выполняется 1 раз в день и вставляет данные в таблицу, необходимо организвание проверку на дублирование в этом запросе.
Объемы данных очень большие, поэтому хотелось бы как проверка выполнялась максимально быстро
Использование что то типа
insert into result
SELECT table_name
FROM t
WHERE NOT EXISTS (
SELECT table_name
FROM result r
WHERE r.table_name = t.table_name);
отрабатывает очень долго.
А удалят записи а потом заново вставлять не подходит
Подскажите какой вариант
26 янв 07, 11:12    [3697755]     Ответить | Цитировать Сообщить модератору
 Re: Дублирование записей  [new]
tru55
Member

Откуда: СПб
Сообщений: 19790
а UNIQUE constraint чем не подходит?
26 янв 07, 11:13    [3697772]     Ответить | Цитировать Сообщить модератору
 Re: Дублирование записей  [new]
dmidek
Member

Откуда: Киев - Дортмунд
Сообщений: 116325
Если в десятке, то вешаем на таблицу ПК и организовываем error_log - таблицу,
куда спокойно будут попадать дубли по ORA-00001.
Если не в десятке можно посмотреть в стороны
PL/SQL-ного FORALL SAVE EXCEPTION с той же идеей.
26 янв 07, 11:15    [3697792]     Ответить | Цитировать Сообщить модератору
 Re: Дублирование записей  [new]
Burya_
Member

Откуда:
Сообщений: 56
dmidek
Если в десятке, то вешаем на таблицу ПК и организовываем error_log - таблицу,
куда спокойно будут попадать дубли по ORA-00001.
Если не в десятке можно посмотреть в стороны
PL/SQL-ного FORALL SAVE EXCEPTION с той же идеей.

Не в 10, мне не надо ни отслеживать дубли ни анализировать их, просто откидывать их
26 янв 07, 11:21    [3697858]     Ответить | Цитировать Сообщить модератору
 Re: Дублирование записей  [new]
Burya_
Member

Откуда:
Сообщений: 56
tru55
а UNIQUE constraint чем не подходит?


Наверное не подойдет, у меня вставляется 2 поля
Номер телефона и месяц
И не вставлять записи только в том случае, если оба поля совпадают
при UNIQUE constraint насколько я знаю он проверяет уже прям при insert и в случае если запись имеется запрос выдаст ошибку, и у меня будет полный откат выполнения транзакции
26 янв 07, 11:24    [3697897]     Ответить | Цитировать Сообщить модератору
 Re: Дублирование записей  [new]
Oleg Ivanov
Member

Откуда: Киев
Сообщений: 289
Burya_
Все привет!
Не подскажите каким образои лучше всего проверить таблицу на дублирование записей
Смысл такой есть запрос, который выполняется 1 раз в день и вставляет данные в таблицу, необходимо организвание проверку на дублирование в этом запросе.
Объемы данных очень большие, поэтому хотелось бы как проверка выполнялась максимально быстро

Burya_
Не в 10, мне не надо ни отслеживать дубли ни анализировать их, просто откидывать их

Если так, то select distinct ...
26 янв 07, 11:25    [3697898]     Ответить | Цитировать Сообщить модератору
 Re: Дублирование записей  [new]
tru55
Member

Откуда: СПб
Сообщений: 19790
Burya_
tru55
а UNIQUE constraint чем не подходит?


Наверное не подойдет, у меня вставляется 2 поля
Номер телефона и месяц
И не вставлять записи только в том случае, если оба поля совпадают
при UNIQUE constraint насколько я знаю он проверяет уже прям при insert и в случае если запись имеется запрос выдаст ошибку, и у меня будет полный откат выполнения транзакции


если перехватишь EXCEPTION, то можно отменить только ошибочный оператор вставки
26 янв 07, 11:28    [3697936]     Ответить | Цитировать Сообщить модератору
 Re: Дублирование записей  [new]
Burya_
Member

Откуда:
Сообщений: 56
Oleg Ivanov
Burya_
Все привет!
Не подскажите каким образои лучше всего проверить таблицу на дублирование записей
Смысл такой есть запрос, который выполняется 1 раз в день и вставляет данные в таблицу, необходимо организвание проверку на дублирование в этом запросе.
Объемы данных очень большие, поэтому хотелось бы как проверка выполнялась максимально быстро

Burya_
Не в 10, мне не надо ни отслеживать дубли ни анализировать их, просто откидывать их

Если так, то select distinct ...


Так а что оно мне даст?
Если при выполнении
insert into res
select s,m from (select s,m from
where a=b
date between '01.01.2007' and to_date('10.01.2007')-1/86400)
В select записи выбираются, если поставлю там distinct не факт что этих записей не будет в результирующей таблице. Тем более если случайно будет запущен тот же запрос
26 янв 07, 11:31    [3697965]     Ответить | Цитировать Сообщить модератору
 Re: Дублирование записей  [new]
Burya_
Member

Откуда:
Сообщений: 56
tru55
Burya_
tru55
а UNIQUE constraint чем не подходит?


Наверное не подойдет, у меня вставляется 2 поля
Номер телефона и месяц
И не вставлять записи только в том случае, если оба поля совпадают
при UNIQUE constraint насколько я знаю он проверяет уже прям при insert и в случае если запись имеется запрос выдаст ошибку, и у меня будет полный откат выполнения транзакции


если перехватишь EXCEPTION, то можно отменить только ошибочный оператор вставки


Не думаю, что это будет отрабатывать быстрее чем NOT Exists(((
26 янв 07, 11:33    [3697983]     Ответить | Цитировать Сообщить модератору
 Re: Дублирование записей  [new]
tru55
Member

Откуда: СПб
Сообщений: 19790
Не думаю, что это будет отрабатывать быстрее чем NOT Exists(((

Енто почему? А попробовать?
26 янв 07, 11:34    [3697999]     Ответить | Цитировать Сообщить модератору
 Re: Дублирование записей  [new]
Burya_
Member

Откуда:
Сообщений: 56
tru55
Не думаю, что это будет отрабатывать быстрее чем NOT Exists(((

Енто почему? А попробовать?


Как раз сейчас этим и занимаюсь)
Может еще какой то вариантик есть?
26 янв 07, 11:36    [3698015]     Ответить | Цитировать Сообщить модератору
 Re: Дублирование записей  [new]
Jannny
Member

Откуда: Спб
Сообщений: 6424
Не понимаю, чем это то Вам не подходит?
26 янв 07, 11:36    [3698016]     Ответить | Цитировать Сообщить модератору
 Re: Дублирование записей  [new]
Jannny
Member

Откуда: Спб
Сообщений: 6424
Jannny
Не понимаю, чем это то Вам не подходит?
...
dmidek
PL/SQL-ного FORALL SAVE EXCEPTION с той же идеей.
26 янв 07, 11:37    [3698026]     Ответить | Цитировать Сообщить модератору
 Re: Дублирование записей  [new]
oragraf
Member

Откуда: Moscow
Сообщений: 1317
dmidek
Если в десятке, то вешаем на таблицу ПК и организовываем error_log - таблицу,
куда спокойно будут попадать дубли по ORA-00001.
Если не в десятке можно посмотреть в стороны
PL/SQL-ного FORALL SAVE EXCEPTION с той же идеей.

+1 Если дубли не нужны для анализа etc, тогда просто игнорировать exception
26 янв 07, 11:39    [3698048]     Ответить | Цитировать Сообщить модератору
 Re: Дублирование записей  [new]
Burya_
Member

Откуда:
Сообщений: 56
oragraf
dmidek
Если в десятке, то вешаем на таблицу ПК и организовываем error_log - таблицу,
куда спокойно будут попадать дубли по ORA-00001.
Если не в десятке можно посмотреть в стороны
PL/SQL-ного FORALL SAVE EXCEPTION с той же идеей.

+1 Если дубли не нужны для анализа etc, тогда просто игнорировать exception


А как мне организовать FORALL у меня очень большие объемы данных.
Насколько я понял FORALL это организцаия цикла
E меня условие, по которому не вставляются записи это сравнения с 2 полями
Таблица с 2 полями
s d
Условие при котором я не вставляю запись = не равно s и не равно d
26 янв 07, 12:11    [3698260]     Ответить | Цитировать Сообщить модератору
 Re: Дублирование записей  [new]
oragraf
Member

Откуда: Moscow
Сообщений: 1317
Burya_

А как мне организовать FORALL у меня очень большие объемы данных.

отбирать данные по кускам(читайте про LIMIT)
CREATE OR REPLACE PROCEDURE tst AS
   rows_limit   CONSTANT INTEGER      := 20000;

   CURSOR cur#tst IS
      SELECT *
        FROM person pe;

   TYPE t_tab#person IS TABLE OF cur#tst%ROWTYPE
      INDEX BY PLS_INTEGER;

   tab#person            t_tab#person;
   isrowfound            BOOLEAN      := TRUE;
BEGIN
   OPEN cur#tst;

   WHILE (isrowfound) LOOP
      FETCH cur#tst
      BULK COLLECT INTO tab#person LIMIT rows_limit;

      isrowfound := cur#tst%FOUND;
/*   <forall ....тут>*/
   END LOOP;
   DBMS_OUTPUT.put_line ('Всего ' || TO_CHAR (cur#tst%ROWCOUNT) || ' строк.');

   CLOSE cur#tst;

   COMMIT;
END;

26 янв 07, 13:03    [3698768]     Ответить | Цитировать Сообщить модератору
 Re: Дублирование записей  [new]
dmidek
Member

Откуда: Киев - Дортмунд
Сообщений: 116325
Burya_
oragraf
dmidek
Если в десятке, то вешаем на таблицу ПК и организовываем error_log - таблицу,
куда спокойно будут попадать дубли по ORA-00001.
Если не в десятке можно посмотреть в стороны
PL/SQL-ного FORALL SAVE EXCEPTION с той же идеей.

+1 Если дубли не нужны для анализа etc, тогда просто игнорировать exception


А как мне организовать FORALL у меня очень большие объемы данных.
Насколько я понял FORALL это организцаия цикла
E меня условие, по которому не вставляются записи это сравнения с 2 полями
Таблица с 2 полями
s d
Условие при котором я не вставляю запись = не равно s и не равно d


ОК.
Смотрите

Connected to Oracle Database 10g Enterprise Edition Release 10.2.0.1.0 
Connected as system


SQL> 
SQL> drop table scott.emp_new
  2  /

Table dropped

SQL> 
SQL> create table scott.emp_new as select * from scott.emp
  2  /

Table created

SQL> 
SQL> insert into scott.emp_new
  2  select * from scott.emp
  3  /

15 rows inserted

SQL> drop table scott.emp_new_2
  2  /

Table dropped

SQL> create table scott.emp_new_2 as select * from scott.emp where 1=0
  2  /

Table created

SQL> 
SQL> alter table scott.emp_new_2 add constraint CST_emp_new_2 PRIMARY KEY (empno)
  2  /

Table altered

SQL> 
SQL> declare
  2  dml_errors EXCEPTION;
  3  PRAGMA EXCEPTION_INIT(dml_errors, -24381);
  4  type typ_emp is record
  5   (empno dbms_sql.number_table,
  6    ename dbms_sql.varchar2_table,
  7    mgr   dbms_sql.number_table,
  8    job   dbms_sql.varchar2_table,
  9    sal   dbms_sql.number_table,
 10    comm  dbms_sql.number_table,
 11    deptno dbms_sql.varchar2_table)
 12   ;
 13  tab_emp typ_emp;
 14  cursor cur_emp is select empno, ename, mgr, job, sal, comm, deptno from scott.emp_new;
 15  begin
 16  open cur_emp;
 17  loop
 18  fetch cur_emp bulk collect into tab_emp.empno, tab_emp.ename, tab_emp.mgr, tab_emp.job, tab_emp.sal, tab_emp.comm,
 19         tab_emp.deptno limit 3;
 20  begin
 21  forall i in 1..tab_emp.empno.count save exceptions
 22  insert into scott.emp_new_2(empno, ename,  mgr, job, sal, comm, deptno)
 23  values(tab_emp.empno(I), tab_emp.ename(I), tab_emp.mgr(I), tab_emp.job(i), tab_emp.sal(i), tab_emp.comm(i),
 24         tab_emp.deptno(i));
 25  exception
 26  when dml_errors then null;
 27  end;
 28  exit when cur_emp%notfound;
 29  end loop;
 30  close cur_emp;
 31  end;
 32  /

PL/SQL procedure successfully completed

SQL> select * from scott.emp_new_2
  2  /

EMPNO ENAME      JOB         MGR HIREDATE          SAL      COMM DEPTNO
----- ---------- --------- ----- ----------- --------- --------- ------
 7369 SMITH      CLERK      7902                800,00               20
 7499 ALLEN      SALESMAN   7698               1600,00    300,00     30
 7521 WARD       SALESMAN   7698               1250,00    500,00     30
 7566 JONES      MANAGER    7839               2975,00               20
 7654 MARTIN     SALESMAN   7698               1250,00   1400,00     30
 7698 BLAKE      MANAGER    7839               2850,00               30
 7782 CLARK      MANAGER    7839               2450,00               10
 7788 SCOTT      ANALYST    7566               3000,00               20
 7839 KING       PRESIDENT                     5000,00               10
 7844 TURNER     SALESMAN   7698               1500,00      0,00     30
 7876 ADAMS      CLERK      7788               1100,00               20
 7900 JAMES      CLERK      7698                950,00               30
 7902 FORD       ANALYST    7566               3000,00               20
 7934 MILLER     CLERK      7782               1300,00               10
  222 ss         ww          222                222,00               40

15 rows selected

SQL> select * from scott.emp_new
  2  /

EMPNO ENAME      JOB         MGR HIREDATE          SAL      COMM DEPTNO
----- ---------- --------- ----- ----------- --------- --------- ------
 7369 SMITH      CLERK      7902 17.12.1980     800,00               20
 7499 ALLEN      SALESMAN   7698 20.02.1981    1600,00    300,00     30
 7521 WARD       SALESMAN   7698 22.02.1981    1250,00    500,00     30
 7566 JONES      MANAGER    7839 02.04.1981    2975,00               20
 7654 MARTIN     SALESMAN   7698 28.09.1981    1250,00   1400,00     30
 7698 BLAKE      MANAGER    7839 01.05.1981    2850,00               30
 7782 CLARK      MANAGER    7839 09.06.1981    2450,00               10
 7788 SCOTT      ANALYST    7566 19.04.1987    3000,00               20
 7839 KING       PRESIDENT       17.11.1981    5000,00               10
 7844 TURNER     SALESMAN   7698 08.09.1981    1500,00      0,00     30
 7876 ADAMS      CLERK      7788 23.05.1987    1100,00               20
 7900 JAMES      CLERK      7698 03.12.1981     950,00               30
 7902 FORD       ANALYST    7566 03.12.1981    3000,00               20
 7934 MILLER     CLERK      7782 23.01.1982    1300,00               10
  222 ss         ww          222 18.01.2007     222,00               40
 7369 SMITH      CLERK      7902 17.12.1980     800,00               20
 7499 ALLEN      SALESMAN   7698 20.02.1981    1600,00    300,00     30
 7521 WARD       SALESMAN   7698 22.02.1981    1250,00    500,00     30
 7566 JONES      MANAGER    7839 02.04.1981    2975,00               20
 7654 MARTIN     SALESMAN   7698 28.09.1981    1250,00   1400,00     30

EMPNO ENAME      JOB         MGR HIREDATE          SAL      COMM DEPTNO
----- ---------- --------- ----- ----------- --------- --------- ------
 7698 BLAKE      MANAGER    7839 01.05.1981    2850,00               30
 7782 CLARK      MANAGER    7839 09.06.1981    2450,00               10
 7788 SCOTT      ANALYST    7566 19.04.1987    3000,00               20
 7839 KING       PRESIDENT       17.11.1981    5000,00               10
 7844 TURNER     SALESMAN   7698 08.09.1981    1500,00      0,00     30
 7876 ADAMS      CLERK      7788 23.05.1987    1100,00               20
 7900 JAMES      CLERK      7698 03.12.1981     950,00               30
 7902 FORD       ANALYST    7566 03.12.1981    3000,00               20
 7934 MILLER     CLERK      7782 23.01.1982    1300,00               10
  222 ss         ww          222 18.01.2007     222,00               40

30 rows selected

SQL> 
26 янв 07, 13:09    [3698800]     Ответить | Цитировать Сообщить модератору
 Re: Дублирование записей  [new]
oragraf
Member

Откуда: Moscow
Сообщений: 1317
dmidek

Уважаемый dmidek, Вы когда преподавали, наверное, учащимся даже домашних заданий не задавали? Имхо, Вы не только разжевали...
26 янв 07, 13:16    [3698851]     Ответить | Цитировать Сообщить модератору
 Re: Дублирование записей  [new]
dmidek
Member

Откуда: Киев - Дортмунд
Сообщений: 116325
oragraf
Имхо, Вы не только разжевали...


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

oragraf

Уважаемый dmidek, Вы когда преподавали, наверное, учащимся даже домашних заданий не задавали?


Задавал - задавал. Я был довольно строгим :-)
26 янв 07, 13:21    [3698903]     Ответить | Цитировать Сообщить модератору
 Re: Дублирование записей  [new]
Stax.
Guest
oragraf
dmidek

Уважаемый dmidek, Вы когда преподавали, наверное, учащимся даже домашних заданий не задавали? Имхо, Вы не только разжевали...

dmidek
SQL> select e.empno, e.ename, sum(e2.sal), sum(e2.comm)
  2  from scott.emp e, scott.emp e2
  3  where e.empno = e2.empno(+)
  4  group by e.empno, e.ename
  5  /


а вот такой вопрос
я обычно пишу
select e.empno, min(e.ename) ename ... group by e.empno
можно наверное и keep но както не привыкну к синтаксису

почему-то для себя (обьяснить не могу) решил что
сорт по ename более дорогая операция чем групповая ф-ція
.....
stax
26 янв 07, 20:22    [3701771]     Ответить | Цитировать Сообщить модератору
 Re: Дублирование записей  [new]
dmidek
Member

Откуда: Киев - Дортмунд
Сообщений: 116325
Stax.
oragraf
dmidek

Уважаемый dmidek, Вы когда преподавали, наверное, учащимся даже домашних заданий не задавали? Имхо, Вы не только разжевали...

dmidek
SQL> select e.empno, e.ename, sum(e2.sal), sum(e2.comm)
  2  from scott.emp e, scott.emp e2
  3  where e.empno = e2.empno(+)
  4  group by e.empno, e.ename
  5  /


а вот такой вопрос
я обычно пишу
select e.empno, min(e.ename) ename ... group by e.empno
можно наверное и keep но както не привыкну к синтаксису

почему-то для себя (обьяснить не могу) решил что
сорт по ename более дорогая операция чем групповая ф-ція
.....
stax


Да, да, конечно, Stax, Вы совершенно правы. Здесь min гораздо лучше.
Но я честно даже не очень думал об этом - просто демонстрировал
преобразование.

Stax, а почему вопрос по теме из другого топика ?
26 янв 07, 22:21    [3702015]     Ответить | Цитировать Сообщить модератору
 Re: Дублирование записей  [new]
Stax.
Guest
dmidek

Stax.
oragraf
dmidek

Уважаемый dmidek, Вы когда преподавали, наверное, учащимся даже домашних заданий не задавали? Имхо, Вы не только разжевали...

dmidek
SQL> select e.empno, e.ename, sum(e2.sal), sum(e2.comm)
  2  from scott.emp e, scott.emp e2
  3  where e.empno = e2.empno(+)
  4  group by e.empno, e.ename
  5  /


а вот такой вопрос
я обычно пишу
select e.empno, min(e.ename) ename ... group by e.empno
можно наверное и keep но както не привыкну к синтаксису

почему-то для себя (обьяснить не могу) решил что
сорт по ename более дорогая операция чем групповая ф-ція
.....
stax


Да, да, конечно, Stax, Вы совершенно правы. Здесь min гораздо лучше.
Но я честно даже не очень думал об этом - просто демонстрировал
преобразование.

Stax, а почему вопрос по теме из другого топика ?

спасиб за ответ
из другого два варианта
1) я напутал
2) подвисает гадюка и после Васк(нескольких) мож слетели ссылки на топик
(не обратил внимание посылал через цитировать)
......
stax
26 янв 07, 22:46    [3702095]     Ответить | Цитировать Сообщить модератору
Все форумы / Oracle Ответить