В качестве примера рассмотрим импорт федерального справочника ОМС "F010" – "Классификатор субъектов Российской Федерации".
Данный справочник имеет следующую структуру:
Элемент root |
|
||
---|---|---|---|
|
Элемент itemN |
Где N – порядковый номер элемента в теге ROOT, входящий в имя тега |
|
|
Атрибут DATEBEG |
|
|
Атрибут KOD_OKATO |
|
||
Атрибут KOD_TF |
|
||
Атрибут OKRUG |
|
||
Атрибут RecId |
|
||
Атрибут SUBNAME |
|
||
|
|
||
|
|
Целевой таблицей импорта в БД МИС МЕДИАЛОГ является внешний справочник OMI_TERR_CODES, имеющий следующую структуру:
Имя поля |
Тип данных |
Название / назначение |
Настройка в GuaService |
---|---|---|---|
OMS_KOD_TER_ID |
int |
Первичный ключ справочника |
Запрещена настройка сопоставления с полями файла |
CODE |
varchar(10) |
Код записи справочника |
Требует сопоставления с полем файла |
LABEL |
varchar(150) |
Наименование субъекта РФ |
Требует сопоставления с полем файла, так как требуется для отображения оператору |
TYPE |
int |
Тип субъекта |
Не требует сопоставления с полями файла |
CODE_KLADR |
varchar(25) |
Код по КЛАДР |
Требует сопоставления с полем файла, так как на поле повязана логика ТЛ пациента |
CODE_OKATO |
varchar(10) |
Код ОКАТО |
Требует сопоставления с полем файла, так как требуется для выгрузки по ОМС. Является ключевым полем справочника ОМС |
PASPORT |
bit |
Требуется паспорт |
Не требует сопоставления с полями файла |
KRN_CREATE_DATE |
datetime |
Дата создания |
Не требует сопоставления с полями файла |
KRN_CREATE_USER_ID |
int |
Пользователь, создавший запись в БД МИС Медиалог |
Не требует сопоставления с полями файла |
KRN_MODIFY_DATE |
datetime |
Дата изменения |
Не требует сопоставления с полями файла |
KRN_MODIFY_USER_ID |
int |
Пользователь, изменивший запись в БД МИС Медиалог |
Не требует сопоставления с полями файла |
KRN_CREATE_DATABASE_ID |
int |
База, в которой создана запись (для репликации) |
Не требует сопоставления с полями файла |
KRN_MODIFY_DATABASE_ID |
int |
База, в которой изменена запись (для репликации) |
Не требует сопоставления с полями файла |
KRN_GUID |
varchar(36) |
Уникальный идентификатор записи по алгоритму GUID |
Не требует сопоставления с полями файла |
ARCHIVE |
bit |
Признак архивной записи |
Требует сопоставления с полем файла, чтобы запретить возможность выбора более не используемой записи |
Сопоставимыми полями в целевой таблице и в XML-файле являются:
XML-файл |
SQL-таблица |
---|---|
Атрибут KOD_OKATO |
CODE_OKATO |
Атрибут KOD_TF |
CODE |
Атрибут SUBNAME |
LABEL |
Дополнительно для SQL-таблицы необходимы поля CODE_KLADR и ARCHIVE:
·Код КЛАДР можно вычислить по КЛАДР-таблице ADR_OBLAST, произведя соответствующее левое внешнее объединение в результирующем sql-запросе по коду ОКАТО.
·Признак архивности всегда имеет значение 0 для записей XML-файла, у которых не заполнена дата окончания действия записи, либо дата окончания больше текущей даты. Поэтому при импорте можно проставить всем записям целевой таблицы признак архивности в значение 1, импорт ограничить только актуальными записями, у которых признак архивности установлен в значение 0.
Пример SQL-кода для парсинга XML-документа и формирования результирующей выборки:
-- Объявляем переменную для XML-документа справочника
DECLARE @XML_TEXT varchar(max);
-- Объявляем переменную для дескриптора разбираемого на сервере XML-документа
DECLARE @idoc int;
-- Заносим в переменную содержимое XML-документа
SET @XML_TEXT = :XML_TEXT;
-- Производит анализ и парсинг XML-документа с помощью системной windows-библиотеки MSXML (Msxmlsql.dll)
-- Таким образом, требования к XML-документу определяются библиотекой MSXML
EXEC sp_xml_preparedocument @idoc OUTPUT, @XML_TEXT;
-- Проверяем, подходит ли по структуре импортируемый документ
IF EXISTS (
SELECT T.CODE, T.LABEL, T.CODE_OKATO, T.DATEEND, 0 ARCHIVE, A.CODE CODE_KLADR
FROM OPENXML (@idoc, '/root//',3)
WITH (CODE varchar(10) '@KOD_TF',
LABEL varchar(150) '@SUBNAME',
CODE_OKATO varchar(10) '@KOD_OKATO',
DATEEND varchar(255) '@DATEEND') T
left join ADR_OBLAST A on left(A.OCATD, 5) = left(T.CODE_OKATO, 5)
WHERE len(isnull(T.CODE_OKATO, '')) > 0
and T.LABEL not like '*%'
and (isnull(T.DATEEND, '') = '' or convert(datetime, T.DATEEND, 104) <= dateadd(day, 1, getdate()))
)
-- Если файл подходит по структуре, то аннулируем все записи справочника
UPDATE dbo.OMI_TERR_CODES SET ARCHIVE = 1;
-- Формируем результирующую выборку. Выборка должна содержать
-- результирующие поля, передаваемые утилите GuaService в качестве содержания обновляемого справочника
-- Результирующие поля должны соответствовать настройке "Соответствие полей" справочника и целевой таблицы импорта
SELECT T.CODE, T.LABEL, T.CODE_OKATO, T.DATEEND, 0 ARCHIVE, A.CODE CODE_KLADR
-- Маска "/root//" означает, что мы обрабатываем все элементы, дочерние к корневому элементу root
FROM OPENXML (@idoc, '/root//',3)
-- Маска "@KOD_TF" означает, что на уровне обрабатываемого элемента мы ищем атрибут KOD_TF
-- Аналогично для масок "@SUBNAME", "@KOD_OKATO", "@DATEEND"
-- Если значения элементов содержатся в тегах, то маску необходимо задавать без значка "@"
WITH (CODE varchar(10) '@KOD_TF',
LABEL varchar(150) '@SUBNAME',
CODE_OKATO varchar(10) '@KOD_OKATO',
DATEEND varchar(255) '@DATEEND') T
-- Объединяем выборку с КЛАДР-таблицей, чтобы корректно заполнить КЛАДР-код
left join ADR_OBLAST A on left(A.OCATD, 5) = left(T.CODE_OKATO, 5)
-- Условия на записи XML-справочника:
-- обязательно должен быть заполнен ОКАТО-код
-- Дата окончания действия записи либо не задана, либо меньше текущей даты
WHERE len(isnull(T.CODE_OKATO, '')) > 0
and T.LABEL not like '*%'
and (isnull(T.DATEEND, '') = '' or convert(datetime, T.DATEEND, 104) <= dateadd(day, 1, getdate()))
-- Освобождаем на сервере ресурсы для XML-документа
EXEC sp_xml_removedocument @idoc