Регистрация

Прошу помощи в экспорте данных из базы DV

Примеры SQL-скриптов, тонкости настройки БД и прочее

Модератор: Модераторы форума

Новичок
Сообщения: 2
Зарегистрирован: 28 окт 2016, 12:46

Прошу помощи в экспорте данных из базы DV

Сообщение GlazunovAG » 28 окт 2016, 18:09

Принесли на днях базу MS SQL на 250Гб и скриншоты из приложения. Поставили задачу - выдернуть из базы справочники, документы и прикрепленные к ним файлы для последующего импорта в другую систему.
Собственно тогда же узнал о существовании DocsVision.

В интернете нашел документ Структура базы данных Docsvision. От разработчика — разработчику!.
С его помощью достаточно быстро получилось выгрузить справочник Сотрудников с должностью и подразделением и Контрагентов с адресами.

Почитав темы на данном форуме, в частности http://forum.idoc.ru/viewtopic.php?f=10&t=8324 написал такой скрипт, чтобы хотя бы приблизительно увидеть что есть в базе по документам. Но большинство результатов запросов вышли пустые и теперь не знаю в какую сторону двигаться.
Таблица [dbo].dvsys_files содержит ~500000 записей, а скрипт возвращает для карточки CardArchive - 1, CardOrd - 6, CardOut - 1. Только для карточки ITU_CardDocument запрос вернул несколько десятков тысяч строк.
Я что-то не так делаю или в базе храниться файлов во много раз больше собственно документов?

Собственно вопрос: как должен выглядеть запрос, чтобы получить цельную единицу документа?
В результате выполнения запроса хотелось бы получить таблицу со следующими полями:
- Вид документа (входящий, исходящий, внутренний, архивный и т.д.),
- Номер документа,
- Дата документа,
- Рег.номер, -
- Дата регистрации,
- Отправитель/Получатель,
- Ответственный/Куратор,
- Подразделение,
- Тема,
- Содержание,
- Контактное лицо,
- Имя файла,
- Ссылка на файл

Такое вообще возможно получить одним запросом? Или для разных документов будет разный набор реквизитов? Никак в голове не уложится эта структура - карточки, секции (((

Еще вопрос по хранимым файлам: в каком виде они хранятся в базе?
Если средствами T-SQL сохранить в файл содержимое поля Data таблицы [dbo].dvsys_binaries, то соответствующая его типу программа (Word для файлов doc, FineReader для файлов pdf и т.д.) не может опознать данный файл за свой.
Файлы хранятся в зашифрованном виде?

Код скрипта:
Код: Выделить всё
DECLARE @cmd nvarchar(1000);
DECLARE @Table varchar(100);

DECLARE @AliasCard varchar(100);
DECLARE @SectMainInfo varchar(100);
DECLARE @TableMainInfo varchar(100);

DECLARE @AliasFileList varchar(100);
DECLARE @SectFileReferencest varchar(100);
DECLARE @TableFileReferencest varchar(100);

DECLARE @AliasCardFile varchar(100);
DECLARE @SectCardFileMainInfo varchar(100);
DECLARE @TableCardFileMainInfo varchar(100);

SET @AliasCard = '%Card%';
SET @SectMainInfo = 'MainInfo';

-------------------------------------------------------------------------------
-- Получаем ID таблицы по секции "Ссылки на файлы" FileReferences карты FileList (Список файлов)
-------------------------------------------------------------------------------
SET @AliasFileList = 'FileList';
SET @SectFileReferencest = 'FileReferences';

-- Получаем ID таблицы по секции Основная информация MainInfo
SELECT @TableFileReferencest = dvsys_sectiondefs.SectionTypeID
  FROM [tevis].[dbo].[dvsys_sectiondefs] AS dvsys_sectiondefs
 WHERE CardTypeID in (SELECT dvsys_carddefs.CardTypeID
                        FROM [tevis].[dbo].[dvsys_carddefs] AS dvsys_carddefs
                       WHERE Alias like @AliasFileList)
       AND Alias = @SectFileReferencest;

SET @TableFileReferencest = '[tevis].[dbo].[dvtable_{' + @TableFileReferencest + '}]';

-------------------------------------------------------------------------------
-- Получаем ID таблицы по секции "Основная информация" MainInfo карты CardFile (Карточка файла)
-------------------------------------------------------------------------------
SET @AliasCardFile = 'CardFile';
SET @SectCardFileMainInfo = 'MainInfo';

-- Получаем ID таблицы по секции Основная информация MainInfo
SELECT @TableCardFileMainInfo = dvsys_sectiondefs.SectionTypeID
  FROM [tevis].[dbo].[dvsys_sectiondefs] AS dvsys_sectiondefs
 WHERE CardTypeID in (SELECT dvsys_carddefs.CardTypeID
                        FROM [tevis].[dbo].[dvsys_carddefs] AS dvsys_carddefs
                       WHERE Alias like @AliasCardFile)
       AND Alias = @SectCardFileMainInfo;

SET @TableCardFileMainInfo = '[tevis].[dbo].[dvtable_{' + @TableCardFileMainInfo + '}]';

DECLARE crsDvSys_CardDefs CURSOR
    FOR
 SELECT DISTINCT [Alias]
   FROM [tevis].[dbo].[dvsys_carddefs]
  WHERE [Alias] like @AliasCard
  ORDER BY [Alias];
                         
OPEN crsDvSys_CardDefs;

FETCH NEXT FROM crsDvSys_CardDefs
 INTO @AliasCard
WHILE @@FETCH_STATUS = 0
BEGIN

        -------------------------------------------------------------------------------
        -- Получаем ID таблицы по секции "Основная информация" MainInfo карты CardInc (Входящие документы)
        -------------------------------------------------------------------------------
   DECLARE crsDvSys_SectionDefs CURSOR
      FOR
    SELECT dvsys_sectiondefs.[SectionTypeID], dvsys_sectiondefs.[Alias]
      FROM [tevis].[dbo].[dvsys_sectiondefs] AS dvsys_sectiondefs
     WHERE CardTypeID in (SELECT dvsys_carddefs.CardTypeID
                      FROM [tevis].[dbo].[dvsys_carddefs] AS dvsys_carddefs
                     WHERE Alias like @AliasCard)
         AND [Alias] = @SectMainInfo;

   OPEN crsDvSys_SectionDefs;

   FETCH NEXT FROM crsDvSys_SectionDefs
    INTO @Table, @AliasTab
   WHILE @@FETCH_STATUS = 0
   BEGIN
    
      SET @Table = '[tevis].[dbo].[dvtable_{' + @Table + '}]';
      
         -------------------------------------------------------------------------------
         -- Получаем данные по документам
         -------------------------------------------------------------------------------
         SELECT @cmd =
         'SELECT ''' + @AliasCard + ''' AS AliasCard, * ' +
         '  from ' + @Table + ' t1 ' +
         '  LEFT JOIN ' + @TableFileReferencest + ' t2 ON t1.FilesID = t2.InstanceID ' +
         '  LEFT JOIN ' + @TableCardFileMainInfo + ' t3 ON t2.CardFileID = t3.InstanceID ' +
         '  LEFT JOIN [tevis].[dbo].[dvsys_files] t4 ON t3.FileID = t4.OwnerCardID ' +
         '  LEFT JOIN [tevis].[dbo].[dvsys_binaries] t5 ON t4.BinaryID = t5.ID';
         EXECUTE (@cmd);
    
      FETCH NEXT FROM crsDvSys_SectionDefs
       INTO @Table, @AliasTab
   END;

   CLOSE crsDvSys_SectionDefs;
   DEALLOCATE crsDvSys_SectionDefs;

   FETCH NEXT FROM crsDvSys_CardDefs
    INTO @AliasCard
END;

CLOSE crsDvSys_CardDefs;
DEALLOCATE crsDvSys_CardDefs;

Гуру
Аватара пользователя
Сообщения: 416
Зарегистрирован: 23 дек 2009, 16:20

Re: Прошу помощи в экспорте данных из базы DV

Сообщение KYCTAPb » 02 дек 2016, 09:33

У Вас весьма нетривиальная задача даже для опытных специалистов по DV. И, я сомневаюсь, чтобы кто-то на форуме её делал (во всяком случае через SQL). Что-то, какую-то часть - возможно. Но чтобы полностью...
Во-первых, версий баз данных по DV может быть несколько. По версиям структура несколько отличается.
Во-вторых, есть такой документ "Описание полей стандартных карточек". Найдите его для соответствующей версии DV. Он Вам серьёзно поможет.
В-третьих. Кратко структура такова (см. описание полей). Есть карточки, есть справочники. Со справочниками у Вас уже что-то получилось. Так вот, про карточки. Карточки имеют секции (несколько). Каждая секция - это какой-то разрез карточки с соответствующей информацией: например "Основная информация", "Сотрудники", "Задачи", "Свойства" и тд. Каждая секция имеет свой идентификатор (см. "Описание полей"). Этот идентификатор - часть названия таблицы в БД. Пр. dvtable_{идентификатор секции}
Секции бывают плоскими (одна строка на секцию карточки. пр. "Основная информация") и табличными (несколько строк на секцию карточки. пр. "Сотрудники"). Как оно увязывается между собой есть в описаниях полей. Кроме того, в полях секций могут содержаться ссылки (RefCard, RefCardID) на другие виды карточек или на справочники.
В-четвёртых, файлов в одной карточке может быть докуя. Кроме того, у каждого файла может быть целая вязанка версий.
В-пятых, всё вышесказанное относится только к стандартному решению. :lol: Если решение кастомное (настроечное или, что еще хуже самописное), то возможны различные варианты отклонений :lol:
Ну и, наконец, в-шестых. Через SQL, несомненно, намного быстрее всё получится, но столько разных нюансов :shock: . Я бы сделал так: поставил нужную версию Докса и сделал из "кубиков" простенький бизнес-процесс, который ищет карточки нужного вида, выбирает из каждой нужную информацию и файлы и складывает всё на диск (или в другую базу) в удобном для импорта виде. И пускай себе крутится - выгружает. Кроме того, можно забацать несколько похожих БП: по разным видам документов и/или по разным периодам. Все (абсолютно все) остальные БП, имеющиеся в системе тормознуть и запустить только те, которые на экспорт. Будет работать весьма шустро.
PS: Ну и конечно, остаётся вариант обратиться к специалистам и не заморачиваться самим

Новичок
Сообщения: 2
Зарегистрирован: 28 окт 2016, 12:46

Re: Прошу помощи в экспорте данных из базы DV

Сообщение GlazunovAG » 02 дек 2016, 10:04

KYCTAPb писал(а):У Вас весьма нетривиальная задача даже для опытных специалистов по DV. И, я сомневаюсь, чтобы кто-то на форуме её делал (во всяком случае через SQL). Что-то, какую-то часть - возможно. Но чтобы полностью...


Спасибо за наводку на документацию, сильно помогла.

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

В итоге задачу решали в несколько этапов (может кому пригодится):
1. Определение карточек с данными. Для этого выполнили следующий запрос

Код: Выделить всё
SELECT t.[CardTypeID]
      ,t2.[Alias]
      ,COUNT(t2.[Alias]) AS Cnt
  FROM [dbo].[dvsys_instances] t
  LEFT JOIN [dbo].[dvsys_carddefs] t2 ON t2.CardTypeID = t.CardTypeID
 GROUP BY t.[CardTypeID], t2.[Alias]
 ORDER BY t2.[Alias];


По количеству записей (более 100000) определили ID и имена Алиасов карточек.
2. По ID и имени Алиаса карточки из таблицы [dbo].[dvsys_carddefs] получили xml описание карточки и список секций.
3. Анализируя xml описание карточки строили SQL запрос для получения данных.

Дальше уже дело техники обработать результат запроса.

Вернуться в SQL в Docsvision

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 1