Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Базы";
Текущий архив: 2006.03.12;
Скачать: [xml.tar.bz2];

Вниз

Вставка в Oracle (ODAC)   Найти похожие ветки 

 
maep   (2006-01-18 08:23) [0]

Граждане, поделитесь опытом.
Есть множество записей, которые необходимо вставить в табличку.
просто insert(...)

В настоящее время реализовано так:

 ResultOraSQL.Prepare;
 cbData.GoToFirst;

 while not cbData.Eof do
 begin
   l  := cbData.GetItem;
   ResultOraSQL.ParamByName("mReq_req_id").AsInteger    := req_id;
   ResultOraSQL.ParamByName("mApp_id").AsInteger        := l.GetFieldInt(0);
   ResultOraSQL.ParamByName(....;

   ResultOraSQL.Execute;

   if k mod (search.index div 20) = 0 then
   begin
     FormGauge.RefreshCountWithDatim2(k,DatimCallToStr(strt));
     OraSession.Commit;
   end;

   inc(k);
 end;

 OraSession.Commit;
 ResultOraSQL.UnPrepare;

Скорость вставки — порядка 400 заисей в секунду Табличка простай, 15 полей, 1 индекс, 1 ключ — вроде не должно быть тормозов)
Мне кажется, тут что-то не так
Заранее спасибо!


 
evvcom ©   (2006-01-18 08:38) [1]

Попробуй определиться сначала, где тормоза. Т.е. напиши курсор на PL/SQL, возвращающий данные, аналогичные cbData, и скармливай из него данные запросу, аналогичному ResultOraSQL, точно так же построчно. Если скорость будет слабо отличаться, то приведенный тобой код, вообще ни о чем не говорит.
P.S. А cbData откуда данные берет? Не с того же оракла?


 
maep   (2006-01-18 09:19) [2]

Тормоза ИМЕННО во время вставки.


 
evvcom ©   (2006-01-18 09:35) [3]


> Тормоза ИМЕННО во время вставки

Где?


 
maep   (2006-01-18 09:41) [4]

Если вставлять данные   в, скажем ,PL\SQL Developer
declare
i number;
begin
for i in 1..10000 loop
insert into secu_result values
(
 101,
 sysdate,
 1,
 sysdate,
 "a",
 i,  
 "aaaaa",
 "aaaaa",
 "aaaaa",
 i,
 "aaaaa",
 "aaaaa",
 "aaaaa",
 "aaaaa",
 "aaaaa",
 "aaaaa",
 "aaaaa",
 "aaaaa"
);

end loop;
end;

то скорость в 10 раз выше


 
maep   (2006-01-18 09:45) [5]

Ткнули носом в компонеот TOraLoader.
Вроде то что надо. Но не могу заставить работать, вылетают ошибки


 
Курдль ©   (2006-01-18 10:11) [6]

А в ODAC есть что-то подобное TOraScript?
Или может быть кверик отработает пакетный запрос?
Если да - можно попробовать сначала набить весь список в запрос, а потом исполнить и закоммитить.


 
maep   (2006-01-18 10:26) [7]

Есть такая штука как TOraLoader
TOraLoader allows to load external data into the Oracle database. It uses direct path load inferface to speed up loading. To specify the name of loading table set TableName property. Use Columns property to access individual columns. Write OnGetColumnData or OnPutData event handlers to read external data and pass it to the database. Call Load method to start loading data.
There are times when you need to put large amount of data to Oracle database. Certainly you may construct INSERT SQL statement and execute it with TOraSQL component. But it takes a lot of time. You can greatly speed up loading time of data by using DML array features. Oracle 8i has better way to do it. With Oracle 8i it is possible using direct path load interface. The direct path load interface allows to access the direct path load engine of the Oracle database server to perform the functions of the Oracle SQL*Loader utility. This functionality provides the ability to load data from external files into Oracle database objects, either a table or a partition of a partitioned table.

ODAC simplifies using direct path load interface by TOraLoader component. TOraLoader allows you to load various formatted data. The capability of TOraLoader component to load various formatted data is reached by reading external data in yourself writing method.
To write your own loader you should:

· create TOraLoader component;

· set name of loading table to TableName;

· create and customize columns which will be loaded (use TOraLoader component editor at design time);

· write your own event handler: OnGetColumnData or OnPutData

· call Load method to start loading.

Кидаю на форму компонент, задаю ему имя таблицы. Он сам создает колонки.
Далее  завожу метод OnPutData, по нажатию кнопки вызываю Load... и все рушится.
Если использовать тип загрузки lmDML, то имеем ORA-24333 что странно,
если lmDirect - то вообще жуткие вещи ORA-00604, ORA-00054

Вот код
procedure TFormMain.PutData(Sender: TOraLoader);
var
 k      : integer;
 req_id : integer;
 strt   : TDateTime;
 l      : CLine;

begin
 strt  := Now;
 FormGauge.OpenGauge(search.index);
 FormGauge.ShowStatus("Экспорт в Oracle");

 req_id := OraSession.ExecProc("secu_add_request",
                     ["USER", "1.1.1.1", SaveOraEDT.Text]);
 req_id := OraSession.ParamByName("RESULT").AsInteger;

 if req_id = -1 then
 begin
   ShowMessage("Ошибка при регистрации заявки");
   exit;
 end;

//  ResultOraSQL.Prepare;
 cbData.GoToFirst;
 k := 0;

 while not cbData.Eof do
 begin
   l  := cbData.GetItem;
   Sender.PutColumnData(0,k+1,req_id);
   Sender.PutColumnData(1,k+1,Now);
   Sender.PutColumnData(2,k+1,l.GetFieldInt(0));
   Sender.PutColumnData(3,k+1,StrToDateTimeFrm("dd.mm.yyyy hh:nn:ss", l.GetField(1, 100)));
   Sender.PutColumnData(4,k+1,l.GetField(2, 1));
   Sender.PutColumnData(5,k+1,l.GetFieldInt(3));
   Sender.PutColumnData(6,k+1,l.GetField(4, 20));
   Sender.PutColumnData(7,k+1,l.GetField(5, 20));
   Sender.PutColumnData(8,k+1,l.GetField(6, 20));
   Sender.PutColumnData(9,k+1,l.GetFieldInt(7));

   inc(k);
 end;

 FormGauge.CloseGauge;
end;


 
evvcom ©   (2006-01-18 10:28) [8]


> А в ODAC есть что-то подобное TOraScript?

Почему подобное? Именно он и есть.

> можно попробовать сначала набить весь список в запрос

Без параметров? Тогда еще дольше будет выполняться. Дополнительные затраты времени на парсинг insert-ов.


 
evvcom ©   (2006-01-18 10:36) [9]


> Есть такая штука как TOraLoader

Ты к нему Demo смотрел? Я нет, но тебе может поможет? См. Demos\Loader.


 
sniknik ©   (2006-01-18 11:17) [10]

попробуй
такое
....
while not cbData.Eof do
begin
  l  := cbData.GetItem;
  ResultOraSQL.ParamByName("mReq_req_id").AsInteger    := req_id;
  ResultOraSQL.ParamByName("mApp_id").AsInteger        := l.GetFieldInt(0);
  ResultOraSQL.ParamByName(....;

  ResultOraSQL.Execute;
.....

заменить на такое
....
mReq_req_idPar:=  ResultOraSQL.ParamByName("mReq_req_id");
mApp_idPar:= ResultOraSQL.ParamByName("mApp_id");
....
while not cbData.Eof do
begin
  l  := cbData.GetItem;
  mReq_req_idPar.AsInteger := req_id;
  mApp_idPar.AsInteger       := l.GetFieldInt(0);
  ....Par:= ....

  ResultOraSQL.Execute;
.....


 
maep   (2006-01-18 11:25) [11]

В общем, заставил работать Loader в ружиме lmDML
В режиме lmDirect происходит СТРАННОЕ.
После вставки пары тысяч записей -
Unknown Error ORA-1041

В режиме lmDML - все рабоатет!
Что это такое!


 
Sergey13 ©   (2006-01-18 11:38) [12]

2[11] maep   (18.01.06 11:25)
>Unknown Error ORA-1041
Что за Оракл? Возможно пропатчить надо. Видимо рвется связь.


 
maep   (2006-01-18 11:57) [13]

Oracle9i Enterprise Edition Release 9.2.0.5.0 - 64bit Production


 
Sergey13 ©   (2006-01-18 12:17) [14]

2 [13] maep   (18.01.06 11:57)
Последняя редакция вроде 9.2.0.6. Я не настаиваю, но посмотреть в эту сторону можно, ИМХО.


 
maep   (2006-01-18 12:23) [15]

Sergey13 ©  , думаю, апдейт базы не состоится:)
будем искать другеи пути? Вряд ли дело в версии, она все таки довольно свежа


 
evvcom ©   (2006-01-18 13:57) [16]


> Вряд ли дело в версии, она все таки довольно свежа

Вряд ли может быть и вряд ли, но апдейт не помешает. 9.2.0.5.0 довольно уже старенький патч.

> Последняя редакция вроде 9.2.0.6.

7 вроде как типа релиз, но есть и упоминания о 8-ом патче. Не знаю, правда, относится ли это к 64bit Production?


 
roottim ©   (2006-01-18 15:22) [17]

а версия ODAC ?

у меня был глюк с загруской по директу, но непомню что именно(номер ошибки) вылезало. Вот что я делал в OraLoader.pas.
процедура DoLoad
заменил else

if StrLComp(PChar(OCIVersionSt), "8.1.7", 5) = 0 then // Bug of 8.1.7
 PieceRows := RowCount
else
 PieceRows := RowCount;// - RowOffset; видимо и 9,2


 
maep   (2006-01-19 04:35) [18]

ODAC 5.50.19
Заменть else чето пока не решаюсь, думаю все ж, неспроста он там:)))


 
roottim ©   (2006-01-19 08:15) [19]

>Заменть else чето пока не решаюсь, думаю все ж, неспроста он там:)))
нашел проблему! заменил, скомпилил - попробовал.
непошло - поставил то, что лежало.


 
maep   (2006-01-19 09:27) [20]

Да видишь ли. Смегнил, скомпилил - заработало...
Потом другой проект - опа, из-за того что ты сменил, не работает. Меняешь обратно..
Переделал чуть старый, опа - не работает...
меняешь..
И так - всю жизнь:) В неуверенности и сомнениях


 
evvcom ©   (2006-01-19 11:53) [21]

Лучше не трогать исходники (это ж генофонд!) Написать свой компонент пусть даже заточенный под приложение, исправив в нем то, что считаешь нужным.



Страницы: 1 вся ветка

Форум: "Базы";
Текущий архив: 2006.03.12;
Скачать: [xml.tar.bz2];

Наверх




Память: 0.5 MB
Время: 0.014 c
2-1140689729
-=Dark=-
2006-02-23 13:15
2006.03.12
Ошибка при запуске Delphi


5-1127113687
kivadim
2005-09-19 11:08
2006.03.12
Что изменить в CheckListBox чтоб галочки не ставились?


15-1140096523
lime
2006-02-16 16:28
2006.03.12
межстрочный интервал


2-1140926399
1Al3dK
2006-02-26 06:59
2006.03.12
неверная печать


1-1139472708
DimaBr
2006-02-09 11:11
2006.03.12
Список компонентов





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский