Имя: Пароль:
1C
1С v8
Скорость экспорта в FireBird
,
0 kanalex
 
01.09.12
23:44
Господа, посоветуйте, что делать у кого был такой опыт.

Есть задача экспортировать всю информацию из 1С в FireBird один раз и потом написать в 1С подписки на события, по которым будут выгружаться измененные или добавленные данные.

Вообщем задача решена, но не радует скорость:(
Не очень большая база (2.5Г) локально в файловом режиме...
Сейчас запущен экспорт всего подряд, что должно экспортироваться.
Всего порядка 65 объектов... справочники, документы и их табличные части, регистры сведений, перечисления...
Компьютер здесь конечно не самый шустрый, но все таки...
Выгрузка длится уже 16 часов.... Боюсь, что завершится она не раньше 20-24-х часов. Файл FireBird сейчас уже 550М.

Можно что-нибудь сделать для ускорения процесса?
8 ПесняПроЗайцев
 
05.09.12
22:15
(5) в свое время я работал с fb, но он многое не умеет, просто бесплатный проект. Сталкивался с тем, что синтаксис tsql немного иной. Что-то изменилось?
9 Адимр
 
06.09.12
00:53
Не знаю как в firebird но в sqlite INSERT INTO FOO SELECT * FROM FOO из 21 итерации (2 млн записей) за 15 секунд на обычной офисной машинке.
10 Чарльз Треч
 
06.09.12
01:09
(0) Это http://www.ibprovider.com/rus/index.html использовать не пробовал?
11 Torquader
 
06.09.12
02:09
(8) Он не то, что не умеет, у него архитектура немного другая.
Если читать документацию про FireBird, то там много всего описано про одновременное исполнение транзакций, уровни блокировок и т.п., половина из которого просто в других серверах не встречается, так как не обеспечивает правильного выполнения транзакций.
Но, в FireBird можно писать SELECT процедуры и выдавать в виде табличного результата произвольный набор данных, что в других SQL просто нет - как объектно-ориентированная игрушка он вполне годится.
Также очень интересный способ использования чисел со смещённой точкой, но вся эта фича поддерживается только при работе в Си через библиотеки.
Ну и массивы - тоже интересная вещь.
12 kanalex
 
06.09.12
10:17
(10) пока не пробовал.
13 kanalex
 
06.09.12
10:18
(4) пока на время отладки база файловая.
Потом будет на скуле, думаю
14 kanalex
 
06.09.12
10:19
(8) в моей задаче ничего хитрого в запросах не приходится делать.
Пока во всяком случае.
15 rs_trade
 
06.09.12
11:27
(13) для скулевой базы я бы экспорт настроил через интегрейшн сервисы.
16 MMF
 
06.09.12
12:55
(0) не надо "Надо собрать каждый запрос и т.д...". Выполняй параметризированные запросы, перед циклом выгрузки сделай их prepared - скорость вырастит в разы.
17 kanalex
 
16.09.12
23:10
Что-то странный результат получился по тестам с IBProvider:(
Или я не так с ним обращаюсь?


Функция СоединитьсяСБазойIBProvider()
   //Установим соединение с БД
   Путь = Константы.тт_СтрокаКоннектаКFireBird.Получить();
   Логин = Константы.тт_ЛогинFireBird.Получить();
   Пароль = Константы.тт_ПарольFireBird.Получить();    
   стрПодключения = "data source="+ Путь + ";user ID= " + Логин + ";password=" + Пароль + "masterkey;auto_commit=true;ctype=win1251";
   Connection = Новый COMОбъект("ADODB.Connection");
   Connection.Provider = "LCPI.IBProvider";
   Connection.ConnectionString = стрПодключения;

   Попытка
       Connection.Open();
   Исключение
       Сообщить ("Проблемы с подключением к InterBase - " + ОписаниеОшибки());
       Возврат "";
   КонецПопытки;
       
   Возврат Connection;    
КонецФункции

Функция СоединитьсяСБазой()
   //Установим соединение с БД
   COMСоединение = Новый COMОбъект("ADODB.Connection");
   Путь = Константы.тт_СтрокаКоннектаКFireBird.Получить();
   Логин = Константы.тт_ЛогинFireBird.Получить();
   Пароль = Константы.тт_ПарольFireBird.Получить();    
   COMСоединение.ConnectionString  = "driver={Firebird/InterBase(r) driver};server=" + Путь + ";uid=" + Логин + ";pwd=" + Пароль + ";database=" + Путь + ";";    
   COMСоединение.ConnectionTimeOut = 1200;
   COMСоединение.CursorLocation    = 3;
   
   Попытка
       COMСоединение.Open(COMСоединение.ConnectionString);
   Исключение
       Отказ = Истина;
       COMСоединение = Неопределено;
       Предупреждение("Невозможно установить соединение - " + ОписаниеОшибки());
   КонецПопытки;
       
   Возврат COMСоединение;    
КонецФункции

Процедура СохранитьРеквизитВТаблицуHEAD(ОбъектADO_proc, TableNameString_proc, TABL_HEAD_ACTV_proc, HeadIDString, TABL_HEAD_TYPE, TABL_HEAD_STAT, TABL_HEAD_1CCO)
   //Запись в таблицу HEAD
   ТекстЗапроса = "INSERT INTO TAB_TABL_HEAD(TABL_HEAD_CODE, TABL_HEAD_NAME, TABL_HEAD_STAT, TABL_HEAD_TYPE, TABL_HEAD_ACTV, TABL_HEAD_SYST, TABL_HEAD_1CCO) VALUES(" + HeadIDString + " , '" + TableNameString_proc + "', " + TABL_HEAD_STAT + ", " + TABL_HEAD_TYPE + ", " + TABL_HEAD_ACTV_proc + ", '" + TABL_HEAD_SYST + "', '" + TABL_HEAD_1CCO + "');";
   ОбъектADO_proc.CommandText = ТекстЗапроса;
   Попытка
       Рекордсет = ОбъектADO_proc.Execute();
   Исключение
       Сообщить(ТекстЗапроса);
       Предупреждение("Не получилось выполнить запрос в таблицу HEAD!" + " - " + ОписаниеОшибки());
       Отказ = Истина;
       Возврат;
   КонецПопытки;    
КонецПроцедуры
   
Процедура Основная()
  Если IBProvider Тогда
     COMСоединение = СоединитьсяСБазойIBProvider();
  Иначе
     COMСоединение = СоединитьсяСБазой();
  КонецЕсли;
  КомандаАДО = КомандаАДО(COMСоединение);

  //Тут для примера.... Там много чего выгружается. Запросы все однотипные в две таблицы поочередно
  //Сначала в HEAD потом в BODY
  Запрос = Новый Запрос;
  Запрос.Текст = "ВЫБРАТЬ " + ИмяПеречисления + ".Ссылка, " + ИмяПеречисления + ".Порядок
                  |ИЗ
                  |    Перечисление." + ИмяПеречисления + " КАК " + ИмяПеречисления;
   
  Состояние("Выполняем выгрузку констант..." + ИмяПеречисления);
  Результат = Запрос.Выполнить();
  Выборка = Результат.Выбрать();
   
  Пока Выборка.Следующий() цикл
     TableNameString = ИмяТаблицы;
     HeadIDString = СгенерироватьID(КомандаАДО, "TABL_HEAD_CODE");
     СохранитьРеквизитВТаблицуHEAD(КомандаАДО, TableNameString, TABL_HEAD_ACTV, HeadIDString, TABL_HEAD_TYPE, TABL_HEAD_STAT, ПолучитьИмяЗначенияПеречисления(Выборка.Ссылка));
     //Запись реквизитов в таблицу BODY            
     СохранитьРеквизитВТаблицуBODY(КомандаАДО, HeadIDString, ИмяРеквизита, Выборка.Ссылка);    //Наименование
  КонецЦикла;    

КонецПроцедуры


Результат теста:
Ограничил по 100 записей в запросах 1С:

IBProvider:
Начали:    16.09.2012 22:34:37
Закончили: 16.09.2012 22:37:12
2 мин 35 сек

Начали:    16.09.2012 22:51:24
Закончили: 16.09.2012 22:53:55
2 мин 31 сек


ODBC:
Начали:    16.09.2012 22:39:05
Закончили: 16.09.2012 22:41:31
2 мин 26 сек

Начали:    16.09.2012 22:47:09
Закончили: 16.09.2012 22:49:33
2 мин 24 сек

Выгружено по 20612 записей в каждом тесте

Что не так???
18 Стальная Крыса
 
17.09.12
06:11
(17) ну в (16) уже было сказано про "prepared"
19 kanalex
 
17.09.12
08:02
(18) к сожалению, не катит prepared:(
Запросы выполняются в цикле в две таблицы поочереди.
Как тут сделать prepared?
20 kanalex
 
17.09.12
12:02
INSERT INTO Students (FirstName,LastName) VALUES ('Иванов','Иван'), ('Петров', 'Петр'), ('Сергеев', 'Сергей')
FB такую конструкцию не понимает (проверил и получил сообщение об ошибке).
21 MMF
 
17.09.12
12:47
(20) Исходя из предположения, что ты единственный пользователь базы на вставку можно получить первое значение генератора для таблицы TAB_TABL_HEAD и вставлять записи без СгенерироватьID, а тупо HeadIDString = HeadIDString + 1;
Не очень понятно, у тебя 1-й записи таблицы HEAD соответствует 1-а запись таблицы Body? странная идея.
Лично я бы сделал примитивную ВК для этого дела и не мучался с IBProvider
22 kanalex
 
17.09.12
12:52
(21) на этапе массового экспорта я единственный..., но потом все это будет привязано к событиям и экспортироваться уже на живой многопользовательской базе. Там я вполне могу оказаться не единственным.
23 kanalex
 
17.09.12
12:54
(21) я привел самый примитивный пример.
Конечно в реальности 1-й записи в Head может соответствовать тысячи записей в Body
24 MMF
 
17.09.12
13:03
(22) ну все равно можно сократить один запрос, используя insert returning, для первичного ключа таблицы-мастера (только сделать поле Pk автоинкрементным)
25 kanalex
 
17.09.12
15:11
Процедура Тест()
   COMСоединение = СоединитьсяСБазой();
   КомандаАДО = КомандаАДО(COMСоединение);
   ТекстЗапроса = "EXECUTE BLOCK AS
                  |BEGIN
                  |INSERT INTO TAB_TABL_HEAD(TABL_HEAD_CODE, TABL_HEAD_NAME, TABL_HEAD_STAT, TABL_HEAD_TYPE, TABL_HEAD_ACTV, TABL_HEAD_SYST, TABL_HEAD_1CCO) VALUES(14 , 'TAB_BOTP_LIST', 1, 1, 0, 'asdsdee553533-ree43', 'rfs-sdff-4563-gfre-9343');
                  |INSERT INTO TAB_TABL_HEAD(TABL_HEAD_CODE, TABL_HEAD_NAME, TABL_HEAD_STAT, TABL_HEAD_TYPE, TABL_HEAD_ACTV, TABL_HEAD_SYST, TABL_HEAD_1CCO) VALUES(15 , 'TAB_BOTP_LIST', 1, 1, 0, 'asdsdee553533-ree43', 'rfs-sdff-4563-gfre-9343');
                  |INSERT INTO TAB_TABL_HEAD(TABL_HEAD_CODE, TABL_HEAD_NAME, TABL_HEAD_STAT, TABL_HEAD_TYPE, TABL_HEAD_ACTV, TABL_HEAD_SYST, TABL_HEAD_1CCO) VALUES(16 , 'TAB_BOTP_LIST', 1, 1, 0, 'asdsdee553533-ree43', 'rfs-sdff-4563-gfre-9343');
                  |END";
   КомандаАДО.CommandText = ТекстЗапроса;
   Попытка
       Рекордсет = КомандаАДО.Execute();
   Исключение
       Сообщить(ТекстЗапроса);
       Предупреждение("Не получилось выполнить запрос в таблицу HEAD!" + " - " + ОписаниеОшибки());
       Отказ = Истина;
       Возврат;
   КонецПопытки;
КонецПроцедуры

Вот такой тест отработал....
Попробуем собирать Блоками. Потестируем...
26 MMF
 
17.09.12
16:04
(25) на длину текста блока есть ограничение. Имхо в 64 кб
27 kanalex
 
17.09.12
17:30
(26)
:( Мда... Короткие блоки исполняются.
28 MMF
 
17.09.12
17:36
(27) ВК спасет отца русской демократии, там и prepared и все что хочешь можно сделать.
Ну а если жестко забиться использованием 1С, то еще попробуй посмотреть настройки базы и сервера: DefaultDbCachePages, ForcedWrites и все остальное прочее.
29 kanalex
 
21.09.12
09:08
(27) выявилось еще более жесткое ограничение:(
Во всяком случае из 1С через ODBC можно выполнить блок с не более чем 255 строк...

тест не показал прироста вообще:(

Для теста взята выгрузка 999 элементов справочника Банки

Без блоков:
Начали: 21.09.2012 8:58:15
Закончили: 21.09.2012 8:59:03

С Блоками:
Начали: 21.09.2012 9:00:24
Закончили: 21.09.2012 9:01:13
30 kanalex
 
25.09.12
12:42
(27) Да, скорость сильно растет.
Но, если что случается с каналом..., то базу не восстановить.
Протестировано: из 10 разрывов связи 9 баз умерло навсегда.
31 kanalex
 
25.09.12
12:44
Еще вопрос возник...
Как лучше экспортировать ХринилищеЗначения?
Надо выгрузить в FB картинки, которые хранятся в базе 1С.
Можно это сделать минуя сохранение в файл? Через запрос.???
32 kanalex
 
25.09.12
15:13
пока результат таков:


       Если СокрЛП(а) =  "Хранилище значения" Тогда
           Если ТипЗнч(Объект.Хранилище.Получить()) = Тип("ДвоичныеДанные") Тогда
               Возврат Строка(Объект.Хранилище.Получить());
           ИначеЕсли Объект.Хранилище.Получить() = Неопределено Тогда
               Возврат "NULL";
           Иначе
               ДвоичныеДанные = Объект.Хранилище.Получить().ПолучитьДвоичныеДанные();
               Возврат Строка(ДвоичныеДанные);
           КонецЕсли;
       КонецЕсли;


Соотв, в запрос попадают двоичные данные обрезанный до 32К:(
33 Jofa
 
25.09.12
15:16
Напиши строку подключения
34 kanalex
 
25.09.12
15:17
Функция СоединитьсяСБазой()
   //Установим соединение с БД
   COMСоединение = Новый COMОбъект("ADODB.Connection");
   Путь = Константы.тт_СтрокаКоннектаКFireBird.Получить();
   Логин = Константы.тт_ЛогинFireBird.Получить();
   Пароль = Константы.тт_ПарольFireBird.Получить();    
   COMСоединение.ConnectionString  = "driver={Firebird/InterBase(r) driver};server=" + Путь + ";uid=" + Логин + ";pwd=" + Пароль + ";database=" + Путь + ";";    
   COMСоединение.ConnectionTimeOut = 1200;
   COMСоединение.CursorLocation    = 3;
   
   Попытка
       COMСоединение.Open(COMСоединение.ConnectionString);
   Исключение
       Отказ = Истина;
       COMСоединение = Неопределено;
       Предупреждение("Невозможно установить соединение - " + ОписаниеОшибки());
   КонецПопытки;
       
   Возврат COMСоединение;    
КонецФункции
35 MMF
 
25.09.12
15:17
(30) "не верю". И что говорит на такую базу IBFirstAidDiagnostic или хотя бы gfix?
36 Jofa
 
25.09.12
15:20
База Локальной сети лежит?
37 Jofa
 
25.09.12
15:23
АЛЛО
38 kanalex
 
25.09.12
15:23
в данном случае при экспорте база лежит на той же машине.
39 Jofa
 
25.09.12
15:25
Добавь в конец вот эту строчку : + ";CHARSET=UTF8"
40 Jofa
 
25.09.12
15:25
Плюсик тоже добавь
41 Jofa
 
25.09.12
15:27
Ну что там у нас получилось?
42 Jofa
 
25.09.12
15:29
Строка подключения должна выглядеть вот так :
COMСоединение.ConnectionString  = "driver={Firebird/InterBase(r) driver};server=" + Путь + ";uid=" + Логин + ";pwd=" + Пароль + ";database=" + Путь + ";"+ ";CHARSET=UTF8";
43 MMF
 
25.09.12
15:29
(32) три раза (в неблагоприятном случае) выполнять Объект.Хранилище.Получить() - мудрое решение
44 Jofa
 
25.09.12
15:30
(42) Поторопился вот так :
COMСоединение.ConnectionString  = "driver={Firebird/InterBase(r) driver};server=" + Путь + ";uid=" + Логин + ";pwd=" + Пароль + ";database=" + Путь + ";CHARSET=UTF8";
45 Jofa
 
25.09.12
15:31
Ну что там?
46 MMF
 
25.09.12
15:32
(44) никакой разницы от твоего чарсета в скорости не будет
47 Jofa
 
25.09.12
15:32
Если не Секрет что там у вас такого сурового храниться в Птичке?
48 kanalex
 
25.09.12
15:32
у нас база в 1251 кодировке лежит
49 Jofa
 
25.09.12
15:33
(46)Ещё как будет . .Ждёмс отчёт
50 Jofa
 
25.09.12
15:33
Укажи 1251
51 Jofa
 
25.09.12
15:35
Ну что там??
52 kanalex
 
25.09.12
15:36
ждемс...
53 Jofa
 
25.09.12
15:37
Надеюсь ты кусочек данных выгружаешь не все?
54 kanalex
 
25.09.12
15:38
естессно:)
все выгружается уже третьи сутки:(
55 Jofa
 
25.09.12
15:38
Если не Секрет что там у вас такого сурового храниться в Птичке ?
56 kanalex
 
25.09.12
15:39
в птичке будет храниться консолидированная база по сети...
1С с этим не справляется.
70 представительств по всей стране. базы 1С объемом до 300Гб:(
57 Jofa
 
25.09.12
15:40
Почему Птичка в Птичке а не СКУЛь?
58 Jofa
 
25.09.12
15:40
Почему в Птичке а не СКУЛь?
59 kanalex
 
25.09.12
15:41
это не ко мне вопрос.
60 Jofa
 
25.09.12
15:41
(56)Круто
61 kanalex
 
25.09.12
15:43
(44)
по 100 записей на запрос:

Начали: 25.09.2012 15:36:09
Закончили: 25.09.2012 15:40:20
62 MMF
 
25.09.12
15:47
(61) выложи скрипт метаданных базы
63 kanalex
 
25.09.12
15:48
(62) FB?
64 kanalex
 
25.09.12
15:49
(44) 5481 + 41996 записей выгрузилось в FB
65 MMF
 
25.09.12
15:51
(63) да
(64) и что, ускорил тебе что-нить чарсет?
66 kanalex
 
25.09.12
15:52
(65) не ускорил
67 MMF
 
25.09.12
15:53
(66) ну дык, ясен перец.
68 kanalex
 
25.09.12
15:56
/******************************************************************************/
/***          Generated by IBExpert 2008.02.18 25.09.2012 15:56:09          ***/
/******************************************************************************/

SET SQL DIALECT 3;

SET NAMES WIN1251;

CREATE DATABASE 'D:\WORK\MM_2012\FbDb\BBB.FDB'
USER 'SYSDBA' PASSWORD 'masterkey'
PAGE_SIZE 16384
DEFAULT CHARACTER SET WIN1251;



/******************************************************************************/
/***                                Domains                                 ***/
/******************************************************************************/

CREATE DOMAIN DOM_CHAR AS
CHAR(1);

CREATE DOMAIN DOM_CODE AS
INTEGER;

CREATE DOMAIN DOM_FLOAT AS
FLOAT;

CREATE DOMAIN DOM_INT AS
INTEGER;

CREATE DOMAIN DOM_ST100 AS
VARCHAR(100);

CREATE DOMAIN DOM_ST13 AS
CHAR(13);

CREATE DOMAIN DOM_ST14 AS
CHAR(14);

CREATE DOMAIN DOM_ST36 AS
CHAR(36);

CREATE DOMAIN DOM_TEXT AS
BLOB SUB_TYPE 1 SEGMENT SIZE 80;

CREATE DOMAIN DOM_TIMESTAMP AS
TIMESTAMP;



/******************************************************************************/
/***                               Generators                               ***/
/******************************************************************************/

CREATE GENERATOR GEN_TABL_BODY_CODE;
SET GENERATOR GEN_TABL_BODY_CODE TO 290946;

CREATE GENERATOR GEN_TABL_HEAD_CODE;
SET GENERATOR GEN_TABL_HEAD_CODE TO 37959;



SET TERM ^ ;



/******************************************************************************/
/***                           Stored Procedures                            ***/
/******************************************************************************/

CREATE PROCEDURE TAB_TABL_BODY_DEL (
   TABL_BODY_CODE INTEGER)
AS
BEGIN
 EXIT;
END^


CREATE PROCEDURE TAB_TABL_BODY_IU (
   TABL_BODY_CODE INTEGER,
   TABL_HEAD_CODE INTEGER,
   TABL_BODY_NAME CHAR(14),
   TABL_BODY_VALT BLOB SUB_TYPE 1 SEGMENT SIZE 80,
   TABL_BODY_VALF FLOAT,
   TABL_BODY_VALI INTEGER,
   TABL_BODY_VALS VARCHAR(100),
   TABL_BODY_TYPE CHAR(1))
AS
BEGIN
 EXIT;
END^


CREATE PROCEDURE TAB_TABL_HEAD_DEL (
   TABL_HEAD_CODE INTEGER)
AS
BEGIN
 EXIT;
END^


CREATE PROCEDURE TAB_TABL_HEAD_IU (
   TABL_HEAD_CODE INTEGER,
   TABL_HEAD_NAME CHAR(13),
   TABL_HEAD_CTST TIMESTAMP,
   TABL_HEAD_STAT INTEGER,
   TABL_HEAD_TYPE INTEGER,
   TABL_HEAD_ACTV INTEGER,
   TABL_HEAD_SYST CHAR(36),
   TABL_HEAD_1CCO CHAR(36))
AS
BEGIN
 EXIT;
END^



SET TERM ; ^


/******************************************************************************/
/***                                 Tables                                 ***/
/******************************************************************************/



CREATE TABLE TAB_TABL_BODY (
   TABL_BODY_CODE  DOM_CODE NOT NULL,
   TABL_HEAD_CODE  DOM_CODE,
   TABL_BODY_NAME  DOM_ST14,
   TABL_BODY_VALT  DOM_TEXT,
   TABL_BODY_VALF  DOM_FLOAT,
   TABL_BODY_VALI  DOM_INT,
   TABL_BODY_VALS  DOM_ST100,
   TABL_BODY_TYPE  DOM_CHAR,
   TABL_BODY_VALD  DOM_TIMESTAMP
);

CREATE TABLE TAB_TABL_HEAD (
   TABL_HEAD_CODE  DOM_CODE NOT NULL,
   TABL_HEAD_NAME  DOM_ST13,
   TABL_HEAD_CTST  DOM_TIMESTAMP DEFAULT current_timestamp,
   TABL_HEAD_STAT  DOM_INT DEFAULT 0,
   TABL_HEAD_TYPE  DOM_INT DEFAULT 0,
   TABL_HEAD_ACTV  DOM_INT DEFAULT 0,
   TABL_HEAD_SYST  DOM_ST36,
   TABL_HEAD_1CCO  DOM_ST36
);



/******************************************************************************/
/***                              Primary Keys                              ***/
/******************************************************************************/

ALTER TABLE TAB_TABL_BODY ADD CONSTRAINT PK_TAB_TABL_BODY PRIMARY KEY (TABL_BODY_CODE);
ALTER TABLE TAB_TABL_HEAD ADD CONSTRAINT PK_TAB_TABL_HEAD PRIMARY KEY (TABL_HEAD_CODE);


/******************************************************************************/
/***                              Foreign Keys                              ***/
/******************************************************************************/

ALTER TABLE TAB_TABL_BODY ADD CONSTRAINT FK_TAB_TABL_BODY_1 FOREIGN KEY (TABL_HEAD_CODE) REFERENCES TAB_TABL_HEAD (TABL_HEAD_CODE);


/******************************************************************************/
/***                                Triggers                                ***/
/******************************************************************************/


SET TERM ^ ;


/******************************************************************************/
/***                          Triggers for tables                           ***/
/******************************************************************************/



/* Trigger: TAB_TABL_BODY_BI */
CREATE TRIGGER TAB_TABL_BODY_BI FOR TAB_TABL_BODY
ACTIVE BEFORE INSERT POSITION 0
AS
BEGIN
 IF (NEW.TABL_BODY_CODE IS NULL) THEN
   NEW.TABL_BODY_CODE = GEN_ID(GEN_TABL_BODY_CODE,1);
END
^

/* Trigger: TAB_TABL_HEAD_BD */
CREATE TRIGGER TAB_TABL_HEAD_BD FOR TAB_TABL_HEAD
ACTIVE BEFORE DELETE POSITION 0
AS
begin
 delete from tab_tabl_body
 where tabl_head_code = old.tabl_head_code;
end
^

SET TERM ; ^



/******************************************************************************/
/***                           Stored Procedures                            ***/
/******************************************************************************/


SET TERM ^ ;

ALTER PROCEDURE TAB_TABL_BODY_DEL (
   TABL_BODY_CODE INTEGER)
AS
begin
 delete from tab_tabl_body
 where (tabl_body_code = :tabl_body_code);
end
^

ALTER PROCEDURE TAB_TABL_BODY_IU (
   TABL_BODY_CODE INTEGER,
   TABL_HEAD_CODE INTEGER,
   TABL_BODY_NAME CHAR(14),
   TABL_BODY_VALT BLOB SUB_TYPE 1 SEGMENT SIZE 80,
   TABL_BODY_VALF FLOAT,
   TABL_BODY_VALI INTEGER,
   TABL_BODY_VALS VARCHAR(100),
   TABL_BODY_TYPE CHAR(1))
AS
begin
 if (exists(select tabl_body_code from tab_tabl_body where (tabl_body_code = :tabl_body_code))) then
   update tab_tabl_body
   set tabl_head_code = :tabl_head_code,
       tabl_body_name = :tabl_body_name,
       tabl_body_valt = :tabl_body_valt,
       tabl_body_valf = :tabl_body_valf,
       tabl_body_vali = :tabl_body_vali,
       tabl_body_vals = :tabl_body_vals,
       tabl_body_type = :tabl_body_type
   where (tabl_body_code = :tabl_body_code);
 else
   insert into tab_tabl_body (
       tabl_body_code,
       tabl_head_code,
       tabl_body_name,
       tabl_body_valt,
       tabl_body_valf,
       tabl_body_vali,
       tabl_body_vals,
       tabl_body_type)
   values (
       :tabl_body_code,
       :tabl_head_code,
       :tabl_body_name,
       :tabl_body_valt,
       :tabl_body_valf,
       :tabl_body_vali,
       :tabl_body_vals,
       :tabl_body_type);
end
^

ALTER PROCEDURE TAB_TABL_HEAD_DEL (
   TABL_HEAD_CODE INTEGER)
AS
begin
 delete from tab_tabl_head
 where (tabl_head_code = :tabl_head_code);
end
^

ALTER PROCEDURE TAB_TABL_HEAD_IU (
   TABL_HEAD_CODE INTEGER,
   TABL_HEAD_NAME CHAR(13),
   TABL_HEAD_CTST TIMESTAMP,
   TABL_HEAD_STAT INTEGER,
   TABL_HEAD_TYPE INTEGER,
   TABL_HEAD_ACTV INTEGER,
   TABL_HEAD_SYST CHAR(36),
   TABL_HEAD_1CCO CHAR(36))
AS
begin
 if (exists(select tabl_head_code from tab_tabl_head where (tabl_head_code = :tabl_head_code))) then
   update tab_tabl_head
   set tabl_head_name = :tabl_head_name,
       tabl_head_ctst = :tabl_head_ctst,
       tabl_head_stat = :tabl_head_stat,
       tabl_head_type = :tabl_head_type,
       tabl_head_actv = :tabl_head_actv,
       tabl_head_syst = :tabl_head_syst,
       tabl_head_1cco = :tabl_head_1cco
   where (tabl_head_code = :tabl_head_code);
 else
   insert into tab_tabl_head (
       tabl_head_code,
       tabl_head_name,
       tabl_head_ctst,
       tabl_head_stat,
       tabl_head_type,
       tabl_head_actv,
       tabl_head_syst,
       tabl_head_1cco)
   values (
       :tabl_head_code,
       :tabl_head_name,
       :tabl_head_ctst,
       :tabl_head_stat,
       :tabl_head_type,
       :tabl_head_actv,
       :tabl_head_syst,
       :tabl_head_1cco);
end
^


SET TERM ; ^


/******************************************************************************/
/***                              Descriptions                              ***/
/******************************************************************************/

DESCRIBE DOMAIN DOM_CHAR
'Символ';

DESCRIBE DOMAIN DOM_CODE
'Уникальный код записи';

DESCRIBE DOMAIN DOM_FLOAT
'Число с плавающей точкой';

DESCRIBE DOMAIN DOM_INT
'Целое число';

DESCRIBE DOMAIN DOM_ST100
'Строка, 100 символов';

DESCRIBE DOMAIN DOM_ST13
'Строка, 13 символов';

DESCRIBE DOMAIN DOM_ST14
'Строка, 14 символов';

DESCRIBE DOMAIN DOM_ST36
'Строка, 36 символов';

DESCRIBE DOMAIN DOM_TEXT
'Текст';

DESCRIBE DOMAIN DOM_TIMESTAMP
'Дата и время';



/******************************************************************************/
/***                              Descriptions                              ***/
/******************************************************************************/

DESCRIBE TABLE TAB_TABL_BODY
'Значения столбцов';

DESCRIBE TABLE TAB_TABL_HEAD
'Таблицы';



/******************************************************************************/
/***                              Descriptions                              ***/
/******************************************************************************/

DESCRIBE PROCEDURE TAB_TABL_BODY_DEL
'Значения стобцов - удаление записи';

DESCRIBE PROCEDURE TAB_TABL_BODY_IU
'Значения стобцов - изменение записи';

DESCRIBE PROCEDURE TAB_TABL_HEAD_DEL
'Таблицы - удаление записи';

DESCRIBE PROCEDURE TAB_TABL_HEAD_IU
'Таблицы - изменение записи';



/******************************************************************************/
/***                              Descriptions                              ***/
/******************************************************************************/

DESCRIBE TRIGGER TAB_TABL_BODY_BI
'Значения столбцов - установка УКЗ';

DESCRIBE TRIGGER TAB_TABL_HEAD_BD
'Таблицы - удаление значений столбцов';



/******************************************************************************/
/***                              Descriptions                              ***/
/******************************************************************************/

DESCRIBE GENERATOR GEN_TABL_BODY_CODE
'Значения столбцов - уникальный код записи';

DESCRIBE GENERATOR GEN_TABL_HEAD_CODE
'Таблицы - уникальный уод записи';



/* Fields descriptions */

DESCRIBE FIELD TABL_BODY_CODE TABLE TAB_TABL_BODY
'Уникальный код записи';

DESCRIBE FIELD TABL_HEAD_CODE TABLE TAB_TABL_BODY
'Код таблицы';

DESCRIBE FIELD TABL_BODY_NAME TABLE TAB_TABL_BODY
'Имя столбца';

DESCRIBE FIELD TABL_BODY_VALT TABLE TAB_TABL_BODY
'Значение - текст';

DESCRIBE FIELD TABL_BODY_VALF TABLE TAB_TABL_BODY
'Значение - число с плавающей точкой';

DESCRIBE FIELD TABL_BODY_VALI TABLE TAB_TABL_BODY
'Значение - целое число';

DESCRIBE FIELD TABL_BODY_VALS TABLE TAB_TABL_BODY
'Значение - строка, 100 символов';

DESCRIBE FIELD TABL_BODY_TYPE TABLE TAB_TABL_BODY
'Тип данных (T - текст, F - число с плавающей точкой, I - целое число, S - строка)';

DESCRIBE FIELD TABL_HEAD_CODE TABLE TAB_TABL_HEAD
'Уникальный код записи';

DESCRIBE FIELD TABL_HEAD_NAME TABLE TAB_TABL_HEAD
'Имя таблицы';

DESCRIBE FIELD TABL_HEAD_CTST TABLE TAB_TABL_HEAD
'Дата и время создания';

DESCRIBE FIELD TABL_HEAD_STAT TABLE TAB_TABL_HEAD
'Состояние (1 - изменение записи, 2 - удаление записи)';

DESCRIBE FIELD TABL_HEAD_TYPE TABLE TAB_TABL_HEAD
'Тип таблицы (1 - простая, 2 - со ссылками, 3 - требует разбора)';

DESCRIBE FIELD TABL_HEAD_ACTV TABLE TAB_TABL_HEAD
'Признак аннулирования (0 - нет, 1 - запись аннулирована)';

DESCRIBE FIELD TABL_HEAD_SYST TABLE TAB_TABL_HEAD
'Код ТП (уникальный идентификатор ТП)';

DESCRIBE FIELD TABL_HEAD_1CCO TABLE TAB_TABL_HEAD
'Код 1С';
69 kanalex
 
25.09.12
15:57
экспортируется в эту базу.
в две таблицы: HEAD и BODY
70 Jofa
 
25.09.12
15:59
Дак а ты в Чарсет что подставлял?
71 Jofa
 
25.09.12
15:59
WIN1251 ?
72 kanalex
 
25.09.12
16:00
(71) да
73 Jofa
 
25.09.12
16:01
Попробуй UTF8
74 kanalex
 
25.09.12
16:01
(43) да, это лишнее.... согласен.
75 Jofa
 
25.09.12
16:03
По пробывал?
76 Jofa
 
25.09.12
16:07
ау
77 kanalex
 
25.09.12
16:08
по 50 записей в запрос:

Начали: 25.09.2012 16:05:46
Закончили: 25.09.2012 16:07:52
78 kanalex
 
25.09.12
16:08
как-то не сильно помогло
79 MMF
 
25.09.12
16:10
(74) открой для себя поле smallint (речь о колонках TABL_HEAD_STAT, TABL_HEAD_ACTV и прочия)
80 Jofa
 
25.09.12
16:11
Ты выгружаешь в Птичку или в 1Ску?
81 kanalex
 
25.09.12
16:11
из 1С в птичку
82 kanalex
 
25.09.12
16:11
обратно тоже будет, но совсем не много
83 MMF
 
25.09.12
17:15
(82) триггер TAB_TABL_HEAD_BD я бы прибил, а во внешнем ключе FK_TAB_TABL_BODY_1 поставил каскадное удаление
84 MMF
 
25.09.12
17:44
сделал маленькую тестовую прогу. Она вставляет в твои таблицы выбранное кол-во записей.
Для 100 000 записей каждого типа и ForcedWrites ON:
Вставка серии целых
Время вставки: 27468
Вставка серии строк
Время вставки: 28249
Всего затрачено: 55717
Для тех же 100 000 и ForcedWrites Off:
Вставка серии целых
Время вставки: 22936
Вставка серии строк
Время вставки: 25250
Всего затрачено: 48186
85 MMF
 
25.09.12
17:47
т.е. скорость вставки: 3590 записей/секунду FW On и 4149 зап/с для FW Off
Такую скорость на обычном железе получишь при использовании ВК, выкинь нафиг свое АДО
86 MMF
 
25.09.12
17:49
мегасофтину можешь скачать тут http://www.onlinedisk.ru/file/950495/
87 MMF
 
25.09.12
17:51
http://www.onlinedisk.ru/file/950497/  слегка подрихтовал скрипт
88 kanalex
 
25.09.12
22:07
(85) примерно в 10 раз быстрее...
89 Ненавижу 1С
 
гуру
25.09.12
22:13
нужны вам какие-то подобия планов обмена, чтобы 150 раз не таскать одни и теже данные
90 kanalex
 
25.09.12
22:17
(89) так одни данные и не таскаются. таскаются ссылки на уже выгруженное.
91 Jofa
 
26.09.12
06:30
(85)А что такое ВК?
92 ILM
 
гуру
26.09.12
06:44
(0) А можно спросить, что за базы, и что за инфа?
Может стоит ограничить уровень детализации для консолидации. Грузить не все, а только агрегированные данные. Если пустили бы к ТЗ, то указал бы на ряд косяков в нём.
93 Jofa
 
26.09.12
06:57
(92) А почему детализацию для консолидации хранят во внешней базеотдельно?
94 kanalex
 
26.09.12
09:19
(91) ВК - внешняя компонента
95 kanalex
 
26.09.12
09:21
(92) - исходные базы - сильно переделанные УТ 10.3
Грузится из них не все, конечно.... Я вообщем, спорил по некоторым моментам, но заказчик настаивает, что ему нужны все цены... за все годы, например. Ну еще там есть подобные моменты.
96 kanalex
 
26.09.12
13:05
Пробуем ВК:
http://infostart.ru/public/15365/
пока не удалось подключить к 8-ке:(

GameWithFire
v8: GameWithFire
щас попробуем...
97 MMF
 
26.09.12
13:18
(96) блин, да сам напиши, не поможет тебе чужая ВК, потому как потеряешь на установке свойств и методов ВК половину выигранного времени - ILanguageExtender тормозная штука
98 kanalex
 
26.09.12
13:21
(97) да не писал я их никогда. Нет времени сейчас на это:(
99 kanalex
 
26.09.12
16:43
обратимся к параметрам...

   ТекстЗапроса = "execute procedure TAB_TABL_HEAD_IU(?, ?, ?, ?, ?, ?, ?, ?);";
   КомандаАДО.CommandText = ТекстЗапроса;
   Параметр1 = КомандаАДО.CreateParameter("TABL_HEAD_CODE",3,1,,2);
   Параметр2 = КомандаАДО.CreateParameter("TABL_HEAD_NAME",8,1,,"А");
   Параметр3 = КомандаАДО.CreateParameter("TABL_HEAD_CTST",7,1,,ТекущаяДата());
   Параметр4 = КомандаАДО.CreateParameter("TABL_HEAD_STAT",3,1,,TABL_HEAD_STAT);
   Параметр5 = КомандаАДО.CreateParameter("TABL_HEAD_TYPE",3,1,,TABL_HEAD_TYPE);
   Параметр6 = КомандаАДО.CreateParameter("TABL_HEAD_ACTV",3,1,,TABL_HEAD_ACTV);
   Параметр7 = КомандаАДО.CreateParameter("TABL_HEAD_SYST",8,1,,тт_ПустаяСсылка);
   Параметр8 = КомандаАДО.CreateParameter("TABL_HEAD_1CCO",8,1,,тт_ПустаяСсылка);    
   КомандаАДО.Parameters.Append(Параметр1);
   КомандаАДО.Parameters.Append(Параметр2);
   КомандаАДО.Parameters.Append(Параметр3);
   КомандаАДО.Parameters.Append(Параметр4);
   КомандаАДО.Parameters.Append(Параметр5);
   КомандаАДО.Parameters.Append(Параметр6);
   КомандаАДО.Parameters.Append(Параметр7);
   КомандаАДО.Parameters.Append(Параметр8);
       Рекордсет = КомандаАДО.Execute();
100 kanalex
 
26.09.12
17:23
Multiple-step OLE DB operation generated errors. Check each OLE DB status value, if available. No work was done

На второй записи...
101 ILM
 
гуру
26.09.12
18:32
(95) Цены за все года? Надеюсь хоть продажные?
102 kanalex
 
26.09.12
21:03
(101) Да, но это тоже не мало:)
При номенклатуре с 10-к тыс. позиций
103 kanalex
 
26.09.12
22:19
(101) почти 90 тыс позиций в запросе к справочнику номенклатуры:)
104 kanalex
 
27.09.12
12:45
ТекстЗапроса = "execute procedure TAB_TABL_HEAD_IU(" + HeadIDString + ", '" + TableNameString_proc + "', current_timestamp, " + TABL_HEAD_STAT + ", " +  TABL_HEAD_TYPE + ", " + TABL_HEAD_ACTV_proc + ", '" +  TABL_HEAD_SYST + "', '" + TABL_HEAD_1CCO + "')";

Вот так отработал цикл. По другому пока не получилось:(
По времени выигрыша нет. На 1000 записях в запросе выигрыш несколько секунд. Это можно считать погрешностью.
105 kanalex
 
27.09.12
12:56
Для а = 100000 По 100900 Цикл
       ТекстЗапроса = "execute procedure TAB_TABL_HEAD_IU(?, ?, current_timestamp, ?, ?, ?, ?, ?);";
       КомандаАДО.CommandText = ТекстЗапроса;
       Параметр1 = КомандаАДО.CreateParameter("TABL_HEAD_CODE",3,1,,а);
       Параметр2 = КомандаАДО.CreateParameter("TABL_HEAD_NAME",8,1,,"А");
       Параметр3 = КомандаАДО.CreateParameter("TABL_HEAD_STAT",3,1,,TABL_HEAD_STAT);
       Параметр4 = КомандаАДО.CreateParameter("TABL_HEAD_TYPE",3,1,,TABL_HEAD_TYPE);
       Параметр5 = КомандаАДО.CreateParameter("TABL_HEAD_ACTV",3,1,,TABL_HEAD_ACTV);
       Параметр6 = КомандаАДО.CreateParameter("TABL_HEAD_SYST",8,1,,тт_ПустаяСсылка);
       Параметр7 = КомандаАДО.CreateParameter("TABL_HEAD_1CCO",8,1,,тт_ПустаяСсылка);    
       КомандаАДО.Parameters.Append(Параметр1);
       КомандаАДО.Parameters.Append(Параметр2);
       КомандаАДО.Parameters.Append(Параметр3);
       КомандаАДО.Parameters.Append(Параметр4);
       КомандаАДО.Parameters.Append(Параметр5);
       КомандаАДО.Parameters.Append(Параметр6);
       КомандаАДО.Parameters.Append(Параметр7);
       Попытка
           Рекордсет = КомандаАДО.Execute();
       Исключение
           Сообщить(ТекстЗапроса + " - " + а);
           Предупреждение("Не получилось выполнить запрос в таблицу HEAD!" + " - " + ОписаниеОшибки());
           Отказ = Истина;
           Возврат;
       КонецПопытки;
   КонецЦикла;

такой тест по-прежнему выдает ошибку на втором шаге цикла:(
106 kanalex
 
27.09.12
15:41
ТекстЗапроса = "execute procedure TAB_TABL_HEAD_IU(?, ?, current_timestamp, ?, ?, ?, ?, ?);";
   Если ОбъектADO_proc.Parameters.Count > 0 Тогда
       Параметр1 = HeadIDString;
       Параметр2 = TableNameString_proc;
       Параметр4 = TABL_HEAD_STAT;
       Параметр5 = TABL_HEAD_TYPE;
       Параметр6 = TABL_HEAD_ACTV_proc;
       Параметр7 = TABL_HEAD_SYST;
       Параметр8 = TABL_HEAD_1CCO;    
   Иначе
       Параметр1 = ОбъектADO_proc.CreateParameter("TABL_HEAD_CODE",3,1,,HeadIDString);
       Параметр2 = ОбъектADO_proc.CreateParameter("TABL_HEAD_NAME",8,1,,TableNameString_proc);
       Параметр3 = ОбъектADO_proc.CreateParameter("TABL_HEAD_STAT",3,1,,TABL_HEAD_STAT);
       Параметр4 = ОбъектADO_proc.CreateParameter("TABL_HEAD_TYPE",3,1,,TABL_HEAD_TYPE);
       Параметр5 = ОбъектADO_proc.CreateParameter("TABL_HEAD_ACTV",3,1,,TABL_HEAD_ACTV_proc);
       Параметр6 = ОбъектADO_proc.CreateParameter("TABL_HEAD_SYST",8,1,,TABL_HEAD_SYST);
       Параметр7 = ОбъектADO_proc.CreateParameter("TABL_HEAD_1CCO",8,1,,TABL_HEAD_1CCO);    
       ОбъектADO_proc.Parameters.Append(Параметр1);
       ОбъектADO_proc.Parameters.Append(Параметр2);
       ОбъектADO_proc.Parameters.Append(Параметр3);
       ОбъектADO_proc.Parameters.Append(Параметр4);
       ОбъектADO_proc.Parameters.Append(Параметр5);
       ОбъектADO_proc.Parameters.Append(Параметр6);
       ОбъектADO_proc.Parameters.Append(Параметр7);    
   КонецЕсли;
   
   ОбъектADO_proc.CommandText = ТекстЗапроса;
   Попытка
       Рекордсет = ОбъектADO_proc.Execute();
   Исключение
       Сообщить(ТекстЗапроса);
       Предупреждение("Не получилось выполнить запрос в таблицу HEAD!" + " - " + ОписаниеОшибки());
       Отказ = Истина;
       Возврат;
   КонецПопытки;

Вот как должно быть! Почти работает....
107 kanalex
 
27.09.12
18:13
Теперь почему-то на втором шаге цикла вылетает из-за отсутствия внешнего ключа при добавлении записи во второй таблице...
Странно:(
Ошибка? Это не ошибка, это системная функция.