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

Откуда:
Сообщений: 77
Народ подскажите, please:

Есть огромная таблица table1 на другом сервере создается table2 и по dblink-у
нужно залить записи в table2, но заливать нужно кусками делая commit
после заливки 10000 записей. Типа


[/src]Insert into table2
  select * 
    from table1@base1
      where dateb between trunc( sysdate - 7 ) and sysdate
[SRC oracle]

Но как прикрутить commit? Не связывая новую и старую таблицы и неупорядачивая старую?
13 ноя 06, 11:22    [3390346]     Ответить | Цитировать Сообщить модератору
 Re: Вставка записей по кускам  [new]
TurBuLenT
Member

Откуда:
Сообщений: 87
P.Spichak

Но как прикрутить commit? Не связывая новую и старую таблицы и неупорядачивая старую?


А зачем коммит? Что бы select count(*) смотреть? Лучше /*+APPEND */ и единственный коммит в конце ...
13 ноя 06, 11:27    [3390389]     Ответить | Цитировать Сообщить модератору
 Re: Вставка записей по кускам  [new]
contr
Member

Откуда:
Сообщений: 1909
Это смотря чем "лить" и как система обращается с "очень большой" таблицей.
Если исходная таблица сама по себе статична - то просто открываем по ней курсор и, прокручивая fetch bulk collect limit 10000 => forall insert с промежуточными commit, получаем желаемое.
Можно попробовать SQL*PLUS COPY и, по месту, динамическую генерацию скрипта SQL*Plus - например, для переноса по разделам.
Но прежде всего надо понять, чем конкретно не устраивает простой insert /*+ append*/ select ...
13 ноя 06, 11:31    [3390420]     Ответить | Цитировать Сообщить модератору
 Re: Вставка записей по кускам  [new]
Aliona
Member

Откуда: Питер
Сообщений: 4023
вот как это предлагают сделать программисты фирмы quest:
автор

-- Copy the data from the renamed table
DECLARE
INSERT_COUNT NUMBER := 1;
CURSOR c1 IS SELECT * from ABT_X SEL_TBL;
BEGIN
FOR r1 IN c1 LOOP
INSERT /*+ APPEND */
INTO ABT INS_TBL
(SYS, BRANCH, PAYEE_SYS, CON_NUM,
CON_DATE, OPEN_DATE, CLOSE_DATE, IS_ARCHIVE,
RP_PERIOD, SERVICE, COMMISSION, TR_ACC,
COMM_ACC, REMARK, CREATED, CREATED_BY,
UPDATED, UPDATED_BY, DEFAULT_SLIP_TYPE, REQUIRED_PAY_PARAM_MASK,
CASHIER_HINT, AB_ID, TAX, TAX_NSP,
COMMISSION_CALC_TYPE, CASH_SIMBOL)
VALUES
(r1.SYS, r1.BRANCH, r1.PAYEE_SYS, r1.CON_NUM,
r1.CON_DATE, r1.OPEN_DATE, r1.CLOSE_DATE, r1.IS_ARCHIVE,
r1.RP_PERIOD, r1.SERVICE, r1.COMMISSION, r1.TR_ACC,
r1.COMM_ACC, r1.REMARK, r1.CREATED, r1.CREATED_BY,
r1.UPDATED, r1.UPDATED_BY, r1.DEFAULT_SLIP_TYPE, r1.REQUIRED_PAY_PARAM_MASK,
r1.CASHIER_HINT, r1.AB_ID, r1.TAX, r1.TAX_NSP,
r1.COMMISSION_CALC_TYPE, r1.CASH_SIMBOL);
-- commit after every 100 inserts to avoid large rollback segments
IF INSERT_COUNT = 100 THEN
COMMIT;
INSERT_COUNT := 1;
ELSE
INSERT_COUNT := INSERT_COUNT + 1;
END IF;
END LOOP;
COMMIT;
END
;

/
13 ноя 06, 16:17    [3392905]     Ответить | Цитировать Сообщить модератору
 Re: Вставка записей по кускам  [new]
contr
Member

Откуда:
Сообщений: 1909
Aliona
вот как это предлагают сделать программисты фирмы quest:
--  Copy the data from the renamed table  
DECLARE 
 INSERT_COUNT NUMBER := 1;
 CURSOR c1 IS SELECT * from ABT_X SEL_TBL;
BEGIN
 FOR r1 IN c1 LOOP
 INSERT /*+ APPEND */
...
 VALUES 
...

Гнать надо таких программистов. Чтобы не советовали всякую дрянь.
13 ноя 06, 16:26    [3392992]     Ответить | Цитировать Сообщить модератору
 Re: Вставка записей по кускам  [new]
Goster
Member

Откуда: Питер->Москва
Сообщений: 438
A transaction containing a direct-path INSERT statement cannot be or become distributed.
13 ноя 06, 16:27    [3393001]     Ответить | Цитировать Сообщить модератору
 Re: Вставка записей по кускам  [new]
dmidek
Member

Откуда: Киев - Дортмунд
Сообщений: 116085
contr
Aliona
вот как это предлагают сделать программисты фирмы quest:
--  Copy the data from the renamed table  
DECLARE 
 INSERT_COUNT NUMBER := 1;
 CURSOR c1 IS SELECT * from ABT_X SEL_TBL;
BEGIN
 FOR r1 IN c1 LOOP
 INSERT /*+ APPEND */
...
 VALUES 
...

Гнать надо таких программистов. Чтобы не советовали всякую дрянь.


Они понимали , что метод медленный
и подумали "Может, хоть так быстрее будет" :-)
13 ноя 06, 16:31    [3393044]     Ответить | Цитировать Сообщить модератору
 Re: Вставка записей по кускам  [new]
dmidek
Member

Откуда: Киев - Дортмунд
Сообщений: 116085
Goster
A transaction containing a direct-path INSERT statement cannot be or become distributed.


Мы уже как-то разбирали эту ситуацию.
Данное ограничение неправильно интерпретируется

Подробности здесь
13 ноя 06, 16:40    [3393146]     Ответить | Цитировать Сообщить модератору
 Re: Вставка записей по кускам  [new]
Proteus
Member

Откуда:
Сообщений: 1348
У меня вот какая идея родилась:
DECLARE
   i INTEGER;
   CURSOR t IS
      SELECT '1'
        FROM dual
      UNION ALL
      SELECT '2' FROM dual;
   TYPE tarr IS TABLE OF NUMBER;
   arr tarr;
BEGIN
   OPEN t;
   LOOP
      FETCH t BULK COLLECT
         INTO arr LIMIT 1;
      EXIT WHEN arr.COUNT = 0;
   
      FORALL i IN arr.FIRST .. arr.LAST
         INSERT INTO test (id) VALUES (arr(i));
   
      INSERT INTO test@remote
         (id)
         SELECT id FROM test;
      commit;   
   END LOOP;
   CLOSE t;
END;

т.е. сначала нарезаем кусок во временную таблицу а потом его вставляем в удаленную ...
13 ноя 06, 17:18    [3393485]     Ответить | Цитировать Сообщить модератору
 Re: Вставка записей по кускам  [new]
Proteus
Member

Откуда:
Сообщений: 1348
Proteus


т.е. сначала нарезаем кусок во временную таблицу а потом его вставляем в удаленную ...


ДА забыл сказать test это GTT.
13 ноя 06, 17:20    [3393500]     Ответить | Цитировать Сообщить модератору
 Re: Вставка записей по кускам  [new]
contr
Member

Откуда:
Сообщений: 1909
Proteus
ДА забыл сказать test это GTT.

fetch bulk collect limit 1 - это воистину революционный подход
13 ноя 06, 17:24    [3393538]     Ответить | Цитировать Сообщить модератору
 Re: Вставка записей по кускам  [new]
dmidek
Member

Откуда: Киев - Дортмунд
Сообщений: 116085
Proteus
Proteus


т.е. сначала нарезаем кусок во временную таблицу а потом его вставляем в удаленную ...


ДА забыл сказать test это GTT.

Совсем не понял этой идеи...
LIMIT 1, промежуточная таблица какая- то ...
Интересен ответ на вопрос contr

contr
Но прежде всего надо понять, чем конкретно не устраивает простой insert /*+ append*/ select ...
13 ноя 06, 17:24    [3393540]     Ответить | Цитировать Сообщить модератору
 Re: Вставка записей по кускам  [new]
Proteus
Member

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

Совсем не понял этой идеи...

Объясняю.
GTT - Global temporary table

1) Открываем курсор на локальную таблицу и читаем из него кусок необходимого размера в массивы. размер указывается в LIMIT ( единица там у меня стоит для того чтоб промежуточный коммит был но об этом позже)
2) из массивов ForAll перекладываем кусок во временную таблицу (с очисткой по коммиту)
3) Простым insert select данные уходят на удаленный сервак. С append или без него это дело другое.
4) Коммит и на следующую итерацию читаем из курсора (открытого ранее) следующий кусок. И для того чтобы этот кусок выделить ненужно ни связывать локальную и удаленную таблицы ни как либо помечать записи в локальной... ИМХО какраз то что хотел автор.
13 ноя 06, 17:38    [3393671]     Ответить | Цитировать Сообщить модератору
 Re: Вставка записей по кускам  [new]
dmidek
Member

Откуда: Киев - Дортмунд
Сообщений: 116085
Proteus
dmidek

Совсем не понял этой идеи...

Объясняю.
GTT - Global temporary table

1) Открываем курсор на локальную таблицу и читаем из него кусок необходимого размера в массивы. размер указывается в LIMIT ( единица там у меня стоит для того чтоб промежуточный коммит был но об этом позже)
2) из массивов ForAll перекладываем кусок во временную таблицу (с очисткой по коммиту)
3) Простым insert select данные уходят на удаленный сервак. С append или без него это дело другое.
4) Коммит и на следующую итерацию читаем из курсора (открытого ранее) следующий кусок. И для того чтобы этот кусок выделить ненужно ни связывать локальную и удаленную таблицы ни как либо помечать записи в локальной... ИМХО какраз то что хотел автор.


Извините, вспомнил малоприличный анекдот про поручика Ржевского
в биллиардной.
Прихожу и все опошляю
"А может мы все-таки сделаем INSERT /*+ APPEND */ SELECT" ?
13 ноя 06, 17:44    [3393740]     Ответить | Цитировать Сообщить модератору
 Re: Вставка записей по кускам  [new]
Proteus
Member

Откуда:
Сообщений: 1348
да я не против /*+ append*/ а даже очень за но бывают таблицы такого размера, что никаких сегментов отката не хватает. тем более что ужно вставлять нв удаленный сервак.
13 ноя 06, 17:48    [3393773]     Ответить | Цитировать Сообщить модератору
 Re: Вставка записей по кускам  [new]
P.Spichak
Member

Откуда:
Сообщений: 77
Да, именно очень здоровая партиционная таблица, Snapshot too old постоянно вылетает на отчетах, есть задача выделить часть данных на другой сервак,
маленькие таблицы переношу impdp через dblink, ну а эту и еще парочку придется так:
[/src]declare 
  subtype mainaR is maina%rowtype;
  type    mainaT is table of mainaR index by pls_integer;
  vMainaT mainaT;
  
  cursor SelMaina
    is
  select m.*
    from table1@cities_link           m
      where m.entried between trunc( sysdate-7 ) and sysdate;
        
begin
  open  selMaina;
  
  loop
  
    fetch SelMaina bulk collect 
      into vMainaT
      limit 10000; 
       
    forall i in 1 .. vMainaT.count
      insert into table2
        values vMainaT(i);  
        
    exit when selMaina%NOTFOUND;          
    commit;
        
  end loop;    
  
  close selMaina;
end;
[SRC oracle]
14 ноя 06, 06:01    [3395075]     Ответить | Цитировать Сообщить модератору
Все форумы / Oracle Ответить