Изменение структуры БД под 1С SQL

В одной из предыдущих статей я рассказал, как при изменении структуры БД в 1с можно добиться того , что бы 1С проходила успешно процедуру верификации. Однако неприятности нас поджидают в дальнейшем при работе с 1С, а именно при изменении данных. Например, при введении нового элемента справочника.При попытке вставки нового элемента 1С выдает ошибку о несоответствии количества передаваемых параметров количеству полей таблицы. Почему это происходит? Дело в том, что при использовании конструкции Insert 1C передает множество полей таблицы без явного указания полей и соответственно MSSQL Server по умолчанию определяет это множество как полный список полей таблицы(без поля с признаком identity).

Материал предоставлен сайтом www.softpoint.ru /

В одной из предыдущих статей я рассказал, как при изменении структуры БД в 1с можно добиться того , что бы 1С проходила успешно процедуру верификации. Однако неприятности нас поджидают в дальнейшем при работе с 1С, а именно при изменении данных. Например, при введении нового элемента справочника.При попытке вставки нового элемента 1С выдает ошибку о несоответствии количества передаваемых параметров количеству полей таблицы. Почему это происходит? Дело в том, что при использовании конструкции Insert 1C передает множество полей таблицы без явного указания полей и соответственно MSSQL Server по умолчанию определяет это множество как полный список полей таблицы(без поля с признаком identity).

Владимир Сердюк

Insert into Sc33 /*если бы 1С передавала бы список
полей то конструкция отрабатывала нормально */ values(.....)

Обойти эту проблему можно с помощью представлений(views). Дело в том что если у нас есть таблица например sc33 и мы создадим представление типа:

create views v_sc33 as select * from sc33

то мы сможем работать с представлением v_sc33 практически также как с таблицей sc33. То есть мы сможем например использовать следующие конструкции:

insert into v_sc33 values(...)
update v_sc33 set descr=' ' where id=' c '
delete from v_sc33 where id =' c '
select * from v_sc33
и т.п.

Нужно также отметить, что проведенные мной тесты показали, что для линейных представлений такого типа оптимизатор отрабатывает корректно и планы запросов такие же, как и для таблиц. Есть определенные нюансы в работе ODBC, а именно в отработке конструкций select с явным указанием индекса, но эта проблема тоже решаема.

Итак. Если мы переименуем таблицы, а взамен них сделаем представления с набором полей указанных в 1С(dds), то таким образом мы сможем "обмануть" 1C.Предположим, у нас есть таблица sc33, к которой репликатор MSSQL добавил дополнительное поле ms_repl_tran. Необходимо переименовать таблицу sc33 например в ##sc33 и создать представление sc33 реализация которой будет select из ##sc33 по всем полям кроме ms_repl_tran.

Create views sc33
As
Select (row_id,id,parentid,code,descr,isfolder,verstamp,sp17)
from ##sc33 -- мы не пишем * т.к. в таблице ##sc33 есть еще поле ms_repl_tran.

После такой реализации 1С будет не видеть дополнительные поля и работать с представлениями как будто с родными таблицами.

Возникает вопрос: а что если уж мы изменяем таблицы и создаем представления, то может сразу убить двух зайцев? Сделать более читабельной структуру 1С? После чего возможно будет строить запросы прямо из query analyzera или настраивать правила репликации по объектам 1С, да много чего еще… В общем-то, в этом нет никакой проблемы. Из 1С нам нужно предварительно выгрузить информацию о соответствии объектов SQL к объектам 1С. Используя например rainbow, мы можем без проблем получить это соответствие в 1С и выгрузить его во внешние SQL таблицы. После чего составив не сложный T-SQL скрипт мы можем переименовать таблицу sc33 не в ##sc33 а в SCТовары и поля соответственно тоже переименовать. В результате у нас получится таблица ScТовары с полями : Row_Id(по моему не имеет смысла переименовывать ), Id ,##Родитель, Код, Наименование, ##ЭтоПапка, ##Версия , Штуки ... (далее идут названия реквизитов). Представление же будет выглядеть следующим образом

Create views sc33
As
Select (row_id ROW_ID ,id ID, ##Родитель PARENTID, Код CODE, Наименование DESCR,##ЭтоПапка ISFOLDER,
##Версия VERSTAMP, Штуки SP17) from SCТовары

Принципиального отличия в работе от первого варианта нет. Для 1С это по прежнему будет все та же таблица sc33 все с теми же полями (row_id,id,parentid,code,descr,isfolder,verstamp,sp17).

Какие проблемы возникают при такой реализации? Во-первых, необходимость при каждом структурном изменении конфигурации возвращать все обратно. Лично я в этом никаких проблем не вижу, т.к. для этого нужно подготовить просто два скрипта - один на изменение структуры, другой на восстановление. Выполняются они за секунды, и я не вижу никаких проблем выполнять его перед структурным изменением и после(нажать два раза кнопку неужели это сложно?:)). Вторая проблема - это ошибка ODBC invalid cursor state, связанная с использованием конструкций с явным использованием index=XXXindex. Она тоже решается, но это пожалуй материал следующих статей.

P.s. У автора данной статьи существует готовое уже прошедшее внедрения решение, которое позволяет с помощью мастера изменений безболезненно изменять структуру 1С, в том числе делать ее более читабельной.

Начать дискуссию