gifts2017

Спуск на уровень СУБД

Опубликовал Евгений Мукомело (ixilimuse) в раздел Программирование - Практика программирования

В данной статье пойдет речь о том как в 1С 8.1-8.2 можно использовать прямые запросы к СУБД MS SQL.
Статья навеяна реальным внедрением. Я постарался описать общие моменты которые необходимо знать для того что бы спуститься на уровень СУБД и начать использовать прямые запросы к СУБД в обход 1С Сервера приложений.

Введение.

В одной из компаний где я когда-то работал, имелась собственная разработка на 1С 8.2 платформе.
Однажды мы пришли к понимаю что наша система работает не очень быстро. Оставалось понять в каком направлении двигаться, что бы оптимизировать работу системы. После долгих исследований и экспериментов, мы решили в серьез взяться за перенос некоторых операций на плечи СУБД, а именно на плечи MS SQL с помощью выполнения прямых запросов на стороне SQL Server, в обход сервера приложений 1С.

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

Cтруктура базы данных 1С на уровне СУБД выглядит не совсем внятно.
Постараюсь описать что же из себя представляет эта структура. Описание будет не полное. Постараюсь описать лишь самое интересное и важное, из того что нужно понимать спускаясь на уровень СУБД.

Рассматриваем структуру хранения данных.

Каждый объект метаданных имеет определенный вид наименования таблиц. Например РегистрСведений начинается с "_InfoRg...", далее идет номер (идентификатор/индекс) регистра. А вот таблички начинающиеся с _InfoRgChng это таблицы содержащие в себе регистрацию изменений в регистре. Перечислять в данной статье все префиксы я не буду. Это можно сделать с помощью средсв 1С. По мере необходимости.

Гораздо интереснее рассказать о других особенностях.
Например о том что в каждой таблице есть внутренний уникальный идентификатор. Индексированное поле. В РегистреСведений это поле _SimpleKey. Его тип данных — binary(16), но фактически в нем хранится значение GUID, зашифрованное в binary. У документов таким полем является поле _Document#N_IDRRef, где N - это индекс документа. У перечисления _IDRRef. И так далее. Это помимо тех идентификаторов которые мы привыкли видеть в 1С. Хотя в самой платформе мы можем получить значение УУИД — это и будет наш GUID.

Ещё интереснее у нас хранятся данные составных полей. Точнее те поля, которые могут примнимать разнотипные значения.
Допустим у нас есть поле. И оно может хранить в себе Строку, Дату, Число, ссылку на справочник клиентов, и ссылку на справочник сотрудников. В 1С мы видим одно единственное поле. На деле же такое поле в базе данных будет иметь ряд полей. Давайте рассмотрим этот пример. Предположим что индекс нашего поля - 8818.

Наименование поля Описание
_Fld8818_TYPE(binary(1)) В данном поле хранится тип значения, который хранится в текущей записи. Тип представляет из себя индекс. Целое число.
_Fld8818_N(Numeric(x)) Здесь будет храниться значение числа. Тип числа (разрядность и длинна равная x) будет зависеть от настроек в самом конфигураторе 1С
_Fld8818_T(datetime) В данном поле будет храниться значение типа Дата и Время
_Fld8818_S(nvarchar(1024)) В этом поле значение в виде строки. Причем длина строки зависит от настроек. 
_Fld8818_RTRef(binary(4)) В данном поле, при условии что в записи хранится ссылка, будет указан тип ссылки. То есть, на какую таблицу ссылается ссылка, справочник это или документ, что за документ или справочник.
_Fld8818_RRRef(binary(16)) А это уже будет сама ссылка на конкретную запись, в конкретной таблице

 

Если с простыми типами данных все ясно, то тип ссылки не так прост.

Наверняка вы зададите вопрос: Как можно определить тип ссылки? То есть, что означает индекс хранящийся в поле _Fld8818_RTRef?
Если мы переведем этот индекс из шестнадцатеричной системы счисления в десятичную, и затем посмотрим на список таблиц базы данных, то обязательно найдем таблицу, в имени которой содержится данный индекс. То есть мы можем по этому индексу получить таблицу, в которой содержится элемент, на который ссылается ссылка в нашем поле.

Зная индекс, мы можем найти необходимую таблицу простым запросом:

Select [TABLE_NAME] 
From INFORMATION_SCHEMA.TABLES
where TABLE_NAME like '%[A-Z,a-z]1950'

Где 1950 — искомый индекс.

Получаем структуру хранения средствами платформы 1С.

Остается вопрос, как нам определить, как некоторая таблица в конфигурации 1С, именуется на уровне СУБД, а так же, соответствие полей на уровне СУБД и конфигурации?
В этом нам поможет встроенная функция поставляемая вместе с платформой:

ПолучитьСтруктуруХраненияБазыДанных()


Данная функция возвращает структуру в которой мы можем по имени объекта в МетаДанных, получить имя объекта в базе данных. Точно так же в структуре содержаться и все поля объектов, и их наименования в базе данных. Но здесь уже начинаются подводные грабли. Которых вроде как и нет, и в тоже время они есть.

Важный момент. При вызове метода, обязательно нужно передать во второй параметр значение «Истина». Что это означает? Этот параметр означает будет ли структура отображать данные в формате 1С: Предприятие, либо в формате СУБД. В чем же разница?

Допустим мы отображаем данные в формате 1С: Предприятие.
Например, если мы попытаемся с помощью этой структуры узнать как называется в базе данных поле «Клиент», то получим к примеру такое имя «Fld1234». Вроде бы все хорошо. Но если мы попытаемся написать запрос к MS SQL:

Select Fld1234 From _InfoReg


Мы в 80% случаев — получим ошибку. Почему? А потому что это лишь общий вид наименования поля. Но стоит знать о том что во первых любое имя поля начинается с нижнего подчеркивания. Казалось бы прибавим к наименованию поля символ "_" и делов то! Но нет. Далее ещё интересней. В зависимости от содержимого поля и его типа, поле имеет определенный постфикс в наименовании. Например RRef — это значит что в поле содержится ссылка. А если просто значение то этого постфикса нет. А помните составные типы данных? Там вообще может быть куча различных постфиксов, при этом полей начинающихся на "_Fld1234" будет гораздо больше чем одно. И как же нам обойти это?
Легко. Те кто знает MS SQL, сразу догадались что на помощь придет системное представление INFORMATION_SCHEMA.COLUMNS
С помощью этого представления мы можем отобрать информацию по наименованию таблицы, и по тому ключевому наименованию поля.
Пример запроса:

Select COLUMN_NAME 
From INFORMATION_SCHEMA.COLUMNS 
where TABLE_NAME like 'ИмяОбъекта(Таблицы)' 
and COLUMN_NAME like 'ПервичноеИмяПоля%'


Данный запрос выдаст нам ряд полей, имена которых начинаются на "_Fld1234". Нам же останется эти данные обработать в нашей программе для использования в запросах к базе.

Но какие минусы у этого метода? Во первых для того что бы обратиться к базе, нам необходимо настроенное подключение к БД, через 1С. То есть дополнительные настройки. Но они нам в любом случае пригодятся, но представьте, у вас большой запрос. Нужно получить имена 20 полей. И каждый раз при этом обращаться к базе и искать там имена полей? Получать и использовать подключение? Это не очень оптимально. Плюс к тому полученные из базы данные, придется ещё как-то обрабатывать. Дополнительные действия. Да и словом - изобретение велосипеда.

Вот тут то нам и приходит на помощь функция

ПолучитьСтруктуруХраненияБазыДанных(,Истина)


Когда значение параметра ИменаБазыДанных = Истина, то функция в результирующую структуру сразу передает всю необходимую информацию по объектам. Включая все физические поля Базы данных. Если поле составное, то в структуре будут видны все физические поля составного поля. Это значительно облегчает нашу работу.

Использование прямых запросов. Отборы. Соединения и обращения через точку.

Как же нам использовать отбор в прямых запросах? Как отобрать данные по конкретному документу? Или по конкретному значению?

Все довольно просто, но снова есть нюансы.

Поля формата Дата. По умолчанию при использовании MS SQL сервера, дата 1С в базу помещается с прибавлением к году 2000. То есть дата в системе 1С «01.01.2013» будет выглядеть как «01.01.4013». Но и это ещё не все. Для того что бы в запросе произвести сравнение даты и оно прошло корректно, нам необходимо дату конвертировать в определенный формат.
По умолчанию в базе данных MSSQL используется формат ymd. Это означает что в дате сперва указан год, месяц и затем число. А выглядит дата следующим образом: 4013-01-01. Для использования в условиях сравнения или для прочих манипуляций нам эту дату нужно обрамлять в опострофы, так же как и строки.

Для преобразования даты в формат SQL я написал для себя такую простенькую функцию:

Функция ДатаВSQL(ЗнДата, Время = Ложь) Экспорт
	Год = Год(ЗнДата);
	Год = Год + 2000;
	Год = Строка(Год);
	Год = СтрЗаменить(Год,Символ(160),"");
	Месяц = Строка(Месяц(ЗнДата));
	День = Строка(День(ЗнДата));
	Месяц = ДобавитьНуль(Месяц, 2);
	День = ДобавитьНуль(День, 2);
	Если Время Тогда
		ЧЧ = ДобавитьНуль(Час(ЗнДата),2);
		ММ = ДобавитьНуль(Минута(ЗнДата),2);
		СС = "00";
		Возврат "'"+Год+"-"+Месяц+"-"+День+" "+ЧЧ+":"+ММ+":"+СС+"'";
	Иначе
		Возврат "'"+Год+"-"+Месяц+"-"+День+"'";
	КонецЕсли;
КонецФункции

Данная функция возвращает готовую дату, в нужном формате в виде строки, остается только подставить в текст запроса. Если у вас в MS SQL по каким то причинам установлен иной формат даты, можно на момент исполнения запроса его поменять. Делается это так:

set dateformat ymd

Либо надо будет переделать представление даты в своем запросе.

Теперь нам нужно отобрать записи по определенному элементу справочника. Как это сделать?
Изначально, когда я не знал о существовании функции ЗначениеВСтрокуВнутр(), для своих нужно я написал пару функций, для получения ссылок на справочники и на документы. Выглядят они так:

Функция ПолучитьВнутрСсылкуПоНомеру(Номер,Объект) Экспорт
    БуфЗапрос = "Select master.dbo.fn_varbintohexstr([_IDRRef]) From _"+ПолучитьНаименованиеОбъектаБД(Объект)+" Where _Number like '"+Строка(Номер)+"'";
    Возврат ПолучитьЗначениеИзБазы(БуфЗапрос);
КонецФункции

Функция ПолучитьВнутрСсылкуПоКоду(Код,Объект) Экспорт
    БуфЗапрос = "Select master.dbo.fn_varbintohexstr([_IDRRef]) From _"+ПолучитьНаименованиеОбъектаБД(Объект)+" Where _Code like '"+Строка(Код)+"'";
    Возврат ПолучитьЗначениеИзБазы(БуфЗапрос);
КонецФункции

Как видно в коде, мы строим простой запрос, и получаем из базы значение ID, которое храниться в базе данных. Объект — это у нас наименование справочника либо документа, а код — код элемента справочника или документа.
Функция master.dbo.fn_varbintohexstr() — позволяет преобразовать значение формата binary в строку.
Но использовать эту функцию — не обазательно.

Полученный ID имеет примерно такой вид: 0xa8ed00221591466911e17da9fd549878
В запросе мы его можем сравнивать как строку

where master.dbo.fn_varbintohexstr(_fld1234RRef) = '0xa8ed00221591466911e17da9fd549878'

Но в таком случае запрос будет отрабатывать дольше. Так как на преобразование в строку тоже нужно время.
Поэтому лучше сравнение делать таким образом:

where _fld1234RRef = 0xa8ed00221591466911e17da9fd549878

Предыдущий вариант использовать можно, но на самом деле, имеется более универсальный и оптимальный способ получить ссылку. Он приведен в функции что показана ниже:

Функция ПолучитьВнутрСсылку(лСсылка) Экспорт
	Если лСсылка = Неопределено Тогда
		Возврат "";
	КонецЕсли;
	Зн = ЗначениеВСтрокуВнутр(лСсылка); //Тот самый метод, о котором я писал выше.
	Зн = "0x" + Лев(Прав(Зн, 33), 32);
	Возврат Зн;
КонецФункции


А давайте представим что нам нужно в запросе сделать внутреннее соединение. И сравнение должно происходить с полем через точку?
То есть, для сравнения нам необходимо проверять одно условие, что дата в основной таблице, равна дате, которая содержится в документе, ссылка на который содержится в присоединяемой таблице.
В 1С это будет выглядеть примерно так

...
ВНУТРЕННЕЕ СОЕДИНЕНИЕ РегистрСведений.СписокДействующих КАК Регистр
По Регистр.Регистратор.Дата = Док.Дата
...

Как же описать это с помощью MS SQL? В том месте запроса, где описываются соединения, компилятор запросов ещё не знает о том что в таблице регистра есть ссылка на регистратор, и что это в свою очередь есть документ, а у этого документа есть дата. Описать ещё одно соединение? Не поможет. Словом я пытался это сделать всяко. Но в итоге решение свелось к вложенному запросу. (если кто-то найдет реальную альтернативу, буду рад узнать ваш способ).

Выше приведенный фрагмент на чистом SQL будет выглядить так:

...
INNER JOIN РегистрСведений.СписокДействующих Register
ON ((select _Date_Time from НашДокумент DocPlan where Register.Источник = DocPlan._IDRRef) = НашаТаблица.DocDate)
...


В запросе мы видим, что во вложенном запросе делаем выборку из таблицы документа, где ID документа равен ID который записан в поле нашей таблицы «Источник», и далее полученное значение _Date_Time сравниваем с датой из нашей таблицы. Все логично и просто. Думаю теперь мы понимаем, во что превращаются наши обращения к полям и объектам через точку, в запросах 1С, когда они транслируются на SQL запрос. И теперь становится понятно почему такие обращения затормаживают работу запросов.

Очень рекомендую вам поэксперементировать с различными запросами, используя инструмент SQL Server Profiler. С его помощью вы сможете увидеть, во что превращаются ваши запросы написанные на языке запросов 1С, пройдя трансляцию на сервере приложений 1С. Особенно интересно вам будет посмотреть что из себя представляют такие виртуальные таблицы как "СрезПоследних".

Тот пример который я описал выше, с внутренним соединеним, 1С сервер скорее всего реализует немного по другому. Но у него свои методы, с использованием переменных, значения которых заполняются серверов приложений перед выполнением запроса.
Ниже я приведу один пример.

Допустим у нас есть запрос в формате 1С:

ВЫБРАТЬ ПЕРВЫЕ 10
	Сроки.Регистратор.ДатаНачала,
	Док.ДатаНачала
ИЗ 
	РегистрСведений.СрокиДоговора КАК Сроки
	ЛЕВОЕ СОЕДИНЕНИЕ Документ.esc_ДСП КАК Док
		ПО Сроки.Регистратор = Док.Ссылка
			И Сроки.Регистратор.ДатаНачала = Док.ДатаНачала

Как мы видим, ситуация аналогичная, как я приводил выше, только соединение не внутреннее, а левое. Как же 1С Сервер приложений траслирует такой запрос?

 Запрос на выходе из 1С Сервера приложений

С помощью SQL Server Profiler мы сможем это увидеть. На картинке выше, показан запрос сервера приложений. Как я и писал выше, мы видим что сервер приложений использует переменные, в которые заранее пишет соответствующие ID. Но нам при использовании прямых запросов, проще было использовать именно вложенный запрос, для нас это универсальное решение, так как не придется подставлять значения переменным.

Будет замечательно если вы самостоятельно изучите различные запросы в таком виде. Возможно это поможет вам оптимизировать ваши запросы.


Для решения каких задач нам могут понадобиться прямые запросы к базе данных?

Думаю данная возможность понадобиться при активной разработки своих собственных решений, либо при реструктуризации готовых решений. В тех случаях, когда в отладочных целях, либо ещё по каким-то причинам, нам придётся переносить большие объемы данных с одной таблицы в другую, либо разбивать данные на несколько таблиц.
Для интеграции 1С с другими, сторонними разработками. Например вывод данных из 1С в какую-нибудь стороннюю программу анализа продаж или что-то похожее.
Оптимизация массивных обработок данных. Когда нам необходимо обработать большое количество данных, при этом внося какие-то изменения, корректировки и т.п. Например копирование записей регистра сведений с изменением какого-либо поля средствами 1С, займет куда больше времени, чем выполнение операции T-SQL Update

Учимся получать доступ к СУБД из 1С.

Для работы с СУБД на прямую, в обход сервера приложений 1С, нам потребуется использовать COM объекты - ADO.
Первым делом нам понадобится строка подключения к базе данных. У нас даже есть возможность формировать эту строку через стандартный интерфейс Windows. Это значительно облегчает процесс подключения к БД.

Настройка подключения к Базе данных
Интерфейс настройки подключения к базе данных.

Давайте рассмотрим пример работы с ADO.

В данном фрагменте кода, мы создаем объект подключения к базе данных. А так же с помощью объекта DataLinks, получаем строку подключения к базе данных используя пользовательский интерфейс настройки этого самого подключения.

Соединение = Новый COMОбъект("ADODB.Connection");
ДатаЛ = Новый COMОбъект("DataLinks");
Соединение.ConnectionString = "Provider=SQLOLEDB.1;Integrated Security=SSPI;"; // Зададим первоначальные настройки, что бы не выбирать руками вид СУБД.
ДатаЛ.PromptEdit(Соединение); // Отобразим диалог настройки подключения к базе (см. рис. 1)
ConnectionString = Соединение.ConnectionString; // Полученную строку присвоим к глобальной переменной, для дальнейшей работы с ней. 
Соединение = Неопределено;

После того как мы получим строку подключения, нам скорее всего захочется отдельные её части разместить на форме, для того что бы пользователь мог исправлять отдельно взятые опции подключения. Следовательно строку необходимо распарсить. Я пока (на момент написания статьи) нашел лишь один способ это сделать, и привожу его ниже. Если кто-то подскажет более элегантный способ парсинга строк, будет здорово.

//Данная функция парсит строку подключения и извлекает необходимое значение
Функция ЗначениеИзСтрокиПодключения(СтрокаПодключения,Значение)
    Результат = "";
    ПозицияСтарта = Найти(СтрокаПодключения,Значение+"=");
    Если ПозицияСтарта > 0 Тогда
        ПозицияСтарта = ПозицияСтарта + СтрДлина(Значение)+1;
    Иначе 
        Возврат Результат;
    КонецЕсли;
    К = ПозицияСтарта;
    Дл = СтрДлина(СтрокаПодключения);
    Пока (Сред(СтрокаПодключения,К,1) <> ";") И (К

Теперь мы сохранили параметры подключения базы данных на форме, при желании можем их сохранить в базу данных. 

Далее надо предусмотреть вариант, когда пользователь (чаще всего мы сами), изменит наименование базы данных или тайм аут прямо в форме обработки, минуя форму редактирования строки подключения. На такой случай создадим такую функцию, которая будет формировать строку подключения собирая данные из визуальных контролов формы. Выглядит она примерно так:

Функция ПолучитьСтрокуПодключения()
    Строка = "Provider=SQLOLEDB.1;";
    Если ЭлементыФормы.флВинАутентификация.Значение Тогда
        Строка = Строка + "Integrated Security=SSPI;"
    Иначе
        Строка = Строка + "Password="+ЭлементыФормы.Пароль.Значение+";";
        Строка = Строка + "Persist Security Info=True;";
        Строка = Строка + "User ID="+ЭлементыФормы.Пользователь.Значение+";";
    КонецЕсли;
    Строка = Строка + "Initial Catalog="+ИмяБазыДанных+";Data Source="+Сервер1С;
    
    Возврат Строка;
КонецФункции

Теперь когда все (или почти все) вопросы со строкой подключения решены, давайте попытаемся воспользоваться ею, для обращения к базе данных.
В первую очередь, думаю нам понадобится функция для проверки подключения. Опишем её таким образом:

// Параметр "CS" - это строка подключения которую мы можем передать для проверки. Если не передаем, 
// то строка собирается из визуальных контролов
Функция ПроверкаПодключения(CS = "")
    
    Соединение = Новый COMОбъект("ADODB.Connection"); //Создаем подключение
    Если CS = "" Тогда 
        СтрокаКоннекта = ПолучитьСтрокуПодключения();
    Иначе
        СтрокаКоннекта = CS;
    КонецЕсли;
    Соединение.ConnectionTimeOut = 6; //Жестко зададим минимальный TimeOut что бы не ждать долго при неудачной попытке.
    Попытка
        Соединение.Open(СтрокаКоннекта);
    Исключение
        Сообщить(ОписаниеОшибки());
        Возврат Ложь;
    КонецПопытки;
    Возврат Истина;
    
КонецФункции

После выполнения данной функции нам станет ясно, можно ли работать дальше, или соединение с базой установить не удалось, и следовательно дальше что-либо делать с подключением — бесполезно. Кстати, для оптимизации функцию получения объекта ADODB.Connection можно разместить в общем модуле, в настройках которого выставлено «Повторное использование». Это позволит не создавать каждый раз новый объект подключения, а будет использоваться уже созданный объект. В теории это позволит сократить время вызова соединения, а так же совсем чуть-чуть сэкономит ресурсы системы.

Если тест подключения к базе проходит нормально, мы можем смело открывать подключение и используя его, обращаться к базе данных. Для того что бы выполнить запрос, нам понадобится объект ADODB.Command. Если наш запрос подразумевает возврат набора записей, или одного значения, в таком случае, нам так же понадобится объект ADODB.RecordSet. Каким образом мы можем работать с этими объектами в 1С? Давайте рассмотрим пример.
Первым делом нам необходимо создать и открыть подключение к базе данных. Делаем это так как показано в примере ниже.

    Соединение = Новый COMОбъект("ADODB.Connection");
    СтрокаКоннекта = ПолучитьСтрокуПодключения();
    Соединение.ConnectionTimeOut = Число(ЭлементыФормы.ТаймАут.Значение);
    Попытка
        Соединение.Open(СтрокаКоннекта);
    Исключение
        Сообщить(ОписаниеОшибки(),СтатусСообщения.ОченьВажное);
        Возврат Неопределено;
    КонецПопытки;

Следующим шагом нам необходимо используя данное подключение, выполнить T-SQL запрос. Следовательно необходимо создать объект ADODB.Command.

ЗапросАДО = Новый COMОбъект("ADODB.Command");
ЗапросАДО.CommandText = "Select * From SomeTable";
ЗапросАДО.ActiveConnection = Соединение;

Причем заметьте, что свойству ActiveConnection мы присваиваем ранее созданное подключение к базе. Теперь когда объект у нас создан, нам остается лишь воспользоваться им. Если нам необходимо просто выполнить запрос, который не вернет никаких результатов, то будет достаточно одной простой команды, которая показана ниже.

ЗапросАДО.Execute();

После выполнения этой команды, в MS SQL будет выполнен T-SQL скрипт, который мы задали в свойстве CommandText у объекта ADODB.Command.
Если же нам необходимо получить какие-то данные из базы, в таком случае нам придется задействовать ещё один компонент: ADODB.RecordSet. Как понятно из названия — это набор записей. И результат выборки нам необходимо поместить именно туда, прежде чем мы сможем этот набор как-то обрабатывать.
Пример использования набора записей приведен ниже.

    Попытка
        НаборЗаписей = Новый COMОбъект("ADODB.ReсordSеt");
        НаборЗаписей = ЗапросАДО.Execute();
    Исключение
        Сообщить(ОписаниеОшибки(),СтатусСообщения.ОченьВажное);
        Возврат Неопределено;
    Конецпопытки;

    Попытка
        НаборЗаписей.MoveFirst();
    Исключение //нет записей в рекордсете
        Сообщить(ОписаниеОшибки(),СтатусСообщения.ОченьВажное);
        Возврат Неопределено;
    КонецПопытки;

    Пока НаборЗаписей.EOF() = 0 Цикл
        Сообщить(Строка(НаборЗаписей.Fields(0).Value));
        НаборЗаписей.MoveNext();
    КонецЦикла;
    
    Соединение.Close();
    ЗапросАДО = Неопределено;
    Соединение = Неопределено;

Как видно в примере, мы выполняем все туже команду ЗапросАДО.Execute(), только на этот раз результат этой команды присваивается объекту НаборЗаписей , который собственно и представляет из себя набор записей ADODB.RecordSet. Когда набор записей получает результат выборки, мы можем этот результат обрабатывать. Но первым делом нам надо сдвинуть курсор с места. Для этого мы выполняем первую команду НаборЗаписей.MoveFirst(). Мы оборачиваем её обработкой исключения потому что если набор записей не будет содержать ни одной строки, то данная команда приведет к ошибке. Поэтому мы намерено отлавливаем данное исключение и в случае если оно происходит, сообщаем об этом пользователю в корректном виде.
Если же записи имеются, то мы открываем цикл, который будет выполняться до тех пор, пока не встретиться конец набора записей. В цикле же мы описываем обработку данных. В своем примере я указал вывод через сообщение(), значения нулевого поля запроса. Но при необходимости мы так же можем присваивать значения в таблицы значений, структуры, массивы и списки значений.

См. также

Подписаться Добавить вознаграждение
Комментарии
1. Dima Dima (bayce) 25.11.13 21:57
2. Яков Коган (Yashazz) 26.11.13 00:33
Всегда задаю один вопрос: а вы уверены, что это не нарушает лицензионное соглашение 1С и что вы не нарушаете законы РФ?
3. Дмитрий Шерстобитов (DitriX) 26.11.13 11:00
(2) та кому какое дело? Если 1с не справляется адекватно с задачами, ради которых ее и купили - то пофиг все эти их законы. И 1С возмущаться не будет, ибо им так выгодно :)

(0) статья какая то не внятная. Ничего толком не ясно.
ПО Сроки.Регистратор = Док.Ссылка
И Сроки.Регистратор.ДатаНачала = Док.ДатаНачала

За такое вообще бью по рукам :) я понимаю что это пример, но из-за такого примера - сразу снижается рейтинг доверия к статье.

Если в двух словах - все что вы тут описали, давно рассматривали на инфостарте. Почитайте смежные ветки, пользуйтесь поиском, и если таки хотите написать - то с ссылками на то, что было ранее :)
ИМХО
4. Юрий Осипов (yuraos) 26.11.13 17:54
А я плюсану, однако.

Сам под 7.7 еще прямыми запросами баловался.
Под 8.х все не так просто с ними получается
...
например для файловых баз до сих пор нет
ни драйверов ODBC ни тем более провайдеров OLEDB.
так что,
использование прямых запросы ограничивается только sql-ными базами.
5. Юрий Осипов (yuraos) 26.11.13 18:00
(4)
Кому интересно, в составе подсистемы
Подсистема "COMExchange" для 1С:Предприятие-8.х (обычное приложение)
имеется консоль, умеющая выполнять через ADO запросы к любым источникам данных,
в том числе к локальной базе данных 1C формата SQL.
6. rhtr Иванов (rhtr) 26.11.13 19:06
Плюс за труды, но вот если бы привёл ещё пример реализации запроса с иерархией, цены бы тебе не было.
ixilimuse; +1 Ответить
7. Андрей Акулов (DrAku1a) 27.11.13 07:12
Сразу "+" - за подробность доступность и открытость изложения!

Для преобразования даты в формат SQL я написал для себя такую простенькую функцию:

Справка по 1С - функция языка "Формат()"
sashocq; V.Nikonov; cleaner_it; vlad.frost; asved.ru; ixilimuse; +6 Ответить
8. Антон Стеклов (asved.ru) 27.11.13 07:40
(3) DitriX,
Если 1с не справляется адекватно с задачами, ради которых ее и купили


Вы не любите кошек? Да вы их просто готовить не умеете.
Есть еще пословица: Нечего на зеркало пенять, коли рожа крива.
Gilev.Vyacheslav; +1 Ответить 1
9. Сергей Карташев (Elisy) 27.11.13 09:22
Для C# если перейти на LINQ, то запросы писать и обновлять данные таблиц становится намного приятнее:
http://www.linq-demo.1csoftware.com/
Evgen.Ponomarenko; cleaner_it; CatMix; comol; ixilimuse; +5 Ответить
10. Дмитрий Шерстобитов (DitriX) 27.11.13 10:38
(8) сразу видно делетанта :) Но ничего - это пройдет.
11. Олег Филиппов (comol) 27.11.13 10:43
Поставил "-", потому что:
1) Баян уж дальше некуда
2) Сама идея зло, "зачем это нужно" описано не о том и не там
3) Метод конечно есть более правильный и быстрый
i.kovtun; Evil Beaver; +2 Ответить
12. Антон Стеклов (asved.ru) 27.11.13 11:10
(10) DitriX, скажите, а "делетант" - это как-то связано с кнопкой Delete, или Вы просто безграмотный хам?
13. Антон Стеклов (asved.ru) 27.11.13 11:12
На всякий случай напоминаю: непосредственная работа с СУБД мало того что является нарушением лицензии, так еще и не гарантирует целостность и непротиворечивость данных в контексте информационной базы 1С.
14. Евгений Пономаренко (Evgen.Ponomarenko) 27.11.13 11:34
(13) asved.ru,
А можно узнать какой конкретно пункт какого лицензионного соглашения нарушается в случае непосредственной работы с СУБД? Вопрос от чистого любопытства...
15. Дмитрий Шерстобитов (DitriX) 27.11.13 11:36
(12) т.е. дилетант - это стало с каких то пор обидным словом? Я, вроде как, вас нигде не обижал.

Давайте обратимся к википедии:
Дилетантизм (дилетантство) (от лат. delecto — услаждаю, забавляю) — занятие какой-либо деятельностью, например, наукой, искусством, ремеслом — без должных знаний и профессиональной подготовки. В современном понимании нередко исходят из приблизительно такого понимания: дилетант не имеет глубоких знаний о предмете своих занятий, поэтому допускает ошибки. Как правило, это человек, ограничивающий масштаб познаний собственным опытом, или суждения которого в отношении чего-либо основаны на поверхностных познаниях.

Если Вы не сталкивались с задачами, которые не может решить 1С, то это говорит о вашем ограниченном опыте ее использования. Тут ничего зазорного нету, главное не бросайте попытки, развивайтесь, и однажды - у Вас появится проект, в котором 1С не будет справляться с определенной частью функционала. Начнется все с ВК, графиков на Яве и т.д., и, возможно, если Вы будете развиваться дальше, то поймете, что бэкап делается средствами SQL, через пару лет, Вы придете к мысли, что вместо ТиИ (точнее часть ее) можно перевести на SQL и выполнять там. И тут то Вы поймете, что Вы нарушаете лицензию 1С (так как ТиИ скульный, в случае нахождения ошибок может их справить, а это внесение изменений в бд минуя механизмы 1С). А делать то нечего, база 600Гигов, ТиИ идет 50часов, а в скуле - 2 часа.

Но не переживайте, у Вас, видимо, еще оооочень много времени до этого этапа.
cleaner_it; ixilimuse; +2 Ответить 1
16. Андрей Овсянкин (Evil Beaver) 27.11.13 11:41
Вроде статья объемная, работа проделана... но, как отметили выше - баянище...
Еще можно подокапываться до некоторых моментов... спорная статья, короче.
Gilev.Vyacheslav; +1 Ответить
17. Антон Стеклов (asved.ru) 27.11.13 12:33
(14) Evgen.Ponomarenko, четвертый, после второй точки.

(15) DitriX, Вы, вероятно, просто не знаете, что ТИИ можно остановить и продолжить. Для задач интеграции есть SOAP, причем этот метод гораздо менее трудоемок. А при массовых изменениях оцените последствия ошибки.

Если Вы не сталкивались с задачами, которые не может решить 1С

Это говорит лишь о том, что я могу позволить себе не заниматься такими задачами. Вам хочется собирать велосипед из самоката, арматуры и синей изоленты - на здоровье. А мне нести ответственность, когда такой велосипед развалится под клиентом, не хочется.

Начнется все с ВК, графиков на Яве и т.д
методология работы с которыми описана в документации по продукту, в отличие от.

бэкап делается средствами SQL
Спасибо, Кэп!

Видите ли, дилетантство определяется не уровнем знаний, а навыком оценки их применимости. Вернее, отсутствием такового.
18. Дмитрий Шерстобитов (DitriX) 27.11.13 12:40
(14) вероятно, имеется ввиду этот пункт http://v8.1c.ru/predpriyatie/questions_licence.htm#28:
65. Для реализации своих задач Организация предполагает изменить структуру некоторых таблиц базы данных. Также предполагается использовать хранимые процедуры и триггеры для реализации обработки данных, реализовать экспорт данных путем прямого чтения таблиц, добавить новые индексы и изменить структуру некоторых индексов. Имеет ли Организация право вносить в систему перечисленные изменения?

Лицензионное соглашение не позволяет использовать недокументированные фирмой "1С" средства для построения решений на платформе 1С:Предприятие. Это означает, что средства СУБД (или любые другие внесистемные средства) можно использовать только в том случае, если документация по продуктам линейки "1С:Предприятие" (включая ИТС) содержит явную рекомендацию использовать данное средство для решения данной задачи.

Во всех остальных случаях лицензионное соглашение позволяет использовать для построения решений только штатные средства платформы. В частности, можно обращаться к данным информационной базы только при помощи объектов "1С:Предприятия", специально предназначенных для работы с данными (запросы, справочники, документы и т.д.). Нельзя обращаться к данным информационной базы напрямую, минуя уровень объектов работы с данными "1С:Предприятия" - например при помощи средств СУБД или при помощи внешних компонент, которые реализуют прямой доступ к СУБД. Это ограничение распространяется на любые действия с данными, в том числе на изменение их структуры, а так же на чтение или изменение самих данных информационной базы или служебных данных "1С:Предприятия".

Данное ограничение необходимо для обеспечения стабильности работы механизмов системы, осуществления поддержки и возможности перехода на новые версии "1С:Предприятия".

Т.е. 1С просто отмазалась красиво, если база крахнулась и они обнаружили, ВНИМАНИЕ!!!, работу с СУДБ напрямую - то Вас еще и штрафанут :)
19. Евгений Пономаренко (Evgen.Ponomarenko) 27.11.13 13:00
(17) asved.ru,
4. Лицензиат обязуется не допускать нарушений исключительных прав Правообладателя на ПРОГРАММНЫЙ ПРОДУКТ, в частности, не совершать и не допускать совершения третьими лицами следующих действий без специального письменного разрешения Правообладателя:

вносить какие-либо изменения в код ПРОГРАММНОГО ПРОДУКТА, содержимое баз данных и других наборов данных, в которых система хранит информацию, за исключением тех изменений, которые вносятся штатными средствами, входящими в состав ПРОГРАММНОГО ПРОДУКТА и описанными в сопроводительной документации;

осуществлять доступ к информационной базе ПРОГРАММНОГО ПРОДУКТА и построение систем на основе ПРОГРАММНОГО ПРОДУКТА с помощью средств и технологических решений, не предусмотренных в сопроводительной документации;

Вы имеете ввиду эти слова?
20. Дмитрий Шерстобитов (DitriX) 27.11.13 13:44
(17)
Вы, вероятно, просто не знаете, что ТИИ можно остановить и продолжить

видать у вас никогда 1С не подвисало, и вы не работали с базами 24/7, где каждый час выбивать надо.
Для задач интеграции есть SOAP, причем этот метод гораздо менее трудоемок

ну да, велосипеду давайте прикрутим еще одну пару педаль. А че? если с одной парой он ездит быстро, то с двумя - в два раза быстрее?. :)
Не пытайтесь умничать, у вас не выходит. СОАП - это протокол трансфера данных, если вы не знали. Т.е. он ТРАНСПОРТИРУЕТ данные, а не ПОЛУЧАЕТ. Ощущаете разницу? Нет? Ну тогда представьте что Вам надо отправить письмо.
И вот, я Вам говорю - что надо написать письмо в ворде, а лицензия 1С разрешает только в текстовом документе. А вы мне парируете - "я использую почту!". Смешно? Ок, вы юзаете почту, а что передавать вы будете? Еще раз - учите мат часть.


Это говорит лишь о том, что я могу позволить себе не заниматься такими задачами.

та можно вообще в экселе кодить, че уж там :)

методология работы с которыми описана в документации по продукту, в отличие от.

(из примера выше) т.е. справка к notepad - отменяет наличие справки к ворду?

Спасибо, Кэп!

Я рад, что помогаю Вам быстрее усвоить материал. Учитесь.

Видите ли, дилетантство определяется не уровнем знаний, а навыком оценки их применимости. Вернее, отсутствием такового.

ноу комментс
21. Евгений Пономаренко (Evgen.Ponomarenko) 27.11.13 13:46
Печальная ситуация получается. В общем-то понятное дело, что модификация структуры и самих данных - тема сама по себе стремная и без лицензионного соглашения, но вот чтение?... выходит, если база упала. А штатные средства оказались не состоятельными, то применение Tool_1CD ведет к нарушению лицензионного соглашения, если на то не было письменного согласия Правообладателя. В принципе применение функции
Глобальный контекст.ПолучитьСтруктуруХраненияБазыДанных предполагает, цитирую документацию:
Следует использовать метод только для административных задач обслуживания базы данных и анализа записей технологического журнала. Не следует применять метод для реализации какой-либо части прикладной функциональности.

для решения задач административных задач обслуживания базы данных и анализа записей технологического журнала применять можно. Но как-то все шатко получается. Радует одно - доказать факт чтения данных третьими инструментами технически не возможно.
22. Александр Чернышов (HEKPOH) 27.11.13 14:02
*запасаюсь попкорном*
Evgen.Ponomarenko; comol; +2 Ответить
23. Дмитрий Шерстобитов (DitriX) 27.11.13 14:43
(21) согласен.
У меня один раз база нагнулось при обновление динамическом (надо было в супер пупер мега отчете добавить галочку для супер мега начальника и супер пупер мега быстро :), к слову - я использовал штатные средства 1С!) так вот, 1с - меня послала куда подальше. Бахнулась структура конфигурации. Пришлось быстро поднимать рядом пустую базу с конфой и тупо перезаливать конфу оттуда в центральную базу.
А 1С мне абсолютно никак не помогла, т.е. тут то и помогать то нечем.

И,если бы я был, честным гражданином, то мне пришлось поднимать бэкап (благо каждый час делается) объяснять всем, что база рухнула и надо теперь все данные перепроверить.
Ах да, перегрузить то даныые с битой базы я не могу - это же "не лицензионно", поэтому давайте ве ручками переносить и восстанавливать.

Короче - все это лицензионное соглашение - нацеленно на то, что бы у 1С были пути отхода, как в случае с ситуацией, когда после установки какой то платформы, у некоторых людей начали гореть ключи. И вот замена ключа - пару недель, а что делать все это время? :)

А 1С, надо отдать им должное,все это понимает, и поэтому ни я, ни кто то из моих знакомых ни разу не слышали про какие то лицензионные войны со стороны 1С.
Evgen.Ponomarenko; +1 Ответить
24. Евгений Пономаренко (Evgen.Ponomarenko) 27.11.13 15:06
Учитывая, что народ уже запасается попкорном, похоже, на то, что щас будет интелектуальный батл.

К стати, на востоке есть присказка "Хочешь познать человека, сразись с ним!"

По поводу правил: хотелось бы заменить, что в технике управляемых конфликтов есть рекомендация:
"Никогда не обвиняйте оппонента в непрофессионализме, обратной дороги не будет.
Не стоит превращать противника во врага."

Люди существа социально зависимые, по этому ущемление статус-кво расценивается как удар ниже пояса.

Напомню в первом раунде противостояния DitriX vs Asved.ru противники обменялись ударами типа "Капитан КЭП"
счет 1:1

Интересно, что нас ждет во втором раунде? Что нового мы узнаем о современных IT технологиях?
chemezov; +1 Ответить
25. Ivan Kovtun (i.kovtun) 27.11.13 15:24
(18)DitriX,
- то Вас еще и штрафанут :)

Не нас, а Вас:)
26. Евгений Пономаренко (Evgen.Ponomarenko) 27.11.13 15:33
(25) i.kovtun,
Желтая карточка ))) давайте не будем переходить на личности...
27. Дмитрий Шерстобитов (DitriX) 27.11.13 15:36
(25) это не я писал, а моя кошка, я ничего такого не знаю, и вообще - попал сюда случайно.
Кошку уже пошел отнес в милицию... Не взяли...
28. Сисой Сисой (Сисой) 27.11.13 15:43
(21) Чтение SQL-базы 1С пмсм вполне лицензионно, если обращаться к ней через 1С-овский же объект ВнешнийИсточникДанных.
29. Дмитрий Шерстобитов (DitriX) 27.11.13 15:57
(28) база то упала :) Или вы предлагает создать новую базу и там подключаясь через внешние источники вытягивать данные?
Не ну логично, но долго.

(25) вы бы еще начали билеты продавать :)
30. Евгений Пономаренко (Evgen.Ponomarenko) 27.11.13 16:01
(28) Сисой,
Ну все, можем считать что совесть успокоили...

И учитывая, что тип "COMОбъект" описан в документации с чистою совестью выполним:

ЗапросАДО = Новый COMОбъект("ADODB.Command");
ЗапросАДО.CommandText = "DROP TABLE SomeTable";
ЗапросАДО.ActiveConnection = Соединение;
ЗапросАДО.Execute();


"Оцi руки нiчого нi чiпали" Ющенко(С)
i.kovtun; yuraos; +2 Ответить 1
31. Василий Казьмин (awk) 27.11.13 16:03
А где вы нашли в лицензии, что прямые запросы это нелицензионное использование?



Лицензиат обязуется не допускать нарушений исключительных прав Правообладателя на ПРОГРАММНЫЙ ПРОДУКТ, в частности, не совершать и не допускать совершения третьими лицами следующих действий без специального письменного разрешения Правообладателя:

распространять ПРОГРАММНЫЙ ПРОДУКТ или отдельные его компоненты;

вносить какие-либо изменения в код ПРОГРАММНОГО ПРОДУКТА, содержимое баз данных и других наборов данных, в которых система хранит информацию, за исключением тех изменений, которые вносятся штатными средствами, входящими в состав ПРОГРАММНОГО ПРОДУКТА и описанными в сопроводительной документации;

осуществлять доступ к информационной базе ПРОГРАММНОГО ПРОДУКТА и построение систем на основе ПРОГРАММНОГО ПРОДУКТА с помощью средств и технологических решений, не предусмотренных в сопроводительной документации;

совершать действия, результатом которых является устранение или снижение эффективности технических средств защиты авторских прав, применяемых Правообладателем, включая применение программных и технических средств "мультиплексирования", средств, изменяющих алгоритм работы программных или аппаратных средств защиты ПРОГРАММНОГО ПРОДУКТА, а также использовать ПРОГРАММНЫЙ ПРОДУКТ с устраненными или измененными без разрешения Правообладателя средствами защиты;

восстанавливать исходный код, декомпилировать и/или деассемблировать программную часть системы, за исключением тех случаев и лишь в той степени, в какой такая деятельность специально разрешена действующим законодательством.

32. Евгений Пономаренко (Evgen.Ponomarenko) 27.11.13 16:13
(31) awk,
дело в том, что не смотря, что сами прямые запросы не описаны в сопроводительной документации, включая диски ИТС, но с легкой руки Сисой, мы теперь можем ломать базы 1С не нарушая лицензионные соглашения 1С.
33. Юрий Осипов (yuraos) 27.11.13 16:26
(30) Evgen.Ponomarenko,
да че уж мелочиться
...
сразу уж
---
ЗапросАДО = Новый COMОбъект("ADODB.Command");
ЗапросАДО.CommandText = 
"DROP DATABASE База1С";
ЗапросАДО.ActiveConnection = Соединение;
ЗапросАДО.Execute();
...Показать Скрыть

:)
и дело с концом!
DitriX; Evgen.Ponomarenko; ixilimuse; +3 Ответить 2
34. Евгений Пономаренко (Evgen.Ponomarenko) 27.11.13 16:39
(33) yuraos,
Вот и сказочке конец...
КомандаСистемы("format c: /u");
35. Юрий Осипов (yuraos) 27.11.13 17:27
(34) Evgen.Ponomarenko,
неа, злые ОДМИНЫ - не дадуть!!!
36. Евгений Пономаренко (Evgen.Ponomarenko) 27.11.13 17:38
(35) yuraos,
ну должна же быть от них хоть какая нибудь польза?...
37. Дмитрий Шерстобитов (DitriX) 27.11.13 18:16
(35) та и (33) не прокатит - если роль входа от 1С настроена с учетом всех политик :)
(36) а как же мешать всем одноэсникам?
Мне всегда казалось что именно это суть их жизни :)
38. Ivan Kovtun (i.kovtun) 27.11.13 18:39
(20) DitriX,
СОАП - это протокол трансфера данных
это имхо заблуждение,
SOAP, originally defined as Simple Object Access Protocol, is a protocol specification for exchanging structured information in the implementation of Web Services in computer networks.
http://en.wikipedia.org/wiki/SOAP

(26) Боже упаси :) Это же "крылатая" фраза, "Операция "Ы".

Я для себя эту дилему решил просто: "это" можно делать, если в разумное время задачу решить невозможно, иначе как прямым вмешательством в БД. Например, я бы наверное обработал скриптом таблицу с BLOB-ом и объемом в 500Гб и 1000000 записей вместо того чтобы поэлементно очищать поле перебором:). И возможно я бы повторил, такой же фокус как DitriX, если бы попал в подобную ситуацию. Но никогда бы не стал рекомендовать интегрироваться прямыми запросами, тем более для постоянного решения. Во-первых если решение будет постоянно использоваться, риски попасть на проблемы с лицензией 1С становятся не иллюзорными. Во-вторых, все-таки нужно думать о тех, кто будет работать после нас.
39. Евгений Пономаренко (Evgen.Ponomarenko) 27.11.13 18:40
(37) DitriX,
)))) а разве Вы не заметили, что начиная с поста 28 тема развивается в альтернативной реальности, где программист, админ сервера и базы данных одно и тоже лицо?
Я боюсь... что вернется топик стартер и удалит меня с поля за весь мой сегодняшний стёб.
На самом деле, полезная статья получилась - спасибо автору за гостеприимство.
40. Дмитрий Шерстобитов (DitriX) 27.11.13 18:57
(38) ну это уже не смешно :)
SOAP, originally defined as Simple Object Access Protocol, is a protocol specification for exchanging structured information in the implementation of Web Services in computer networks.

Там может и не быть структуры как таковой :) главное - структура запроса и всдл. и все. данные - могут быть любыми. Я так понял именно это вас и смутило :) Там даже байты можно передавать, только в всдл укажите заранее это.

Давайте еще раз - СОАП - это протокол ПЕРЕДАЧИ данных, а не ПОЛУЧЕНИЯ :) Что бы что то передать - это надо где то взять.

Например, я бы наверное обработал скриптом таблицу с BLOB-ом и объемом в 500Гб и 1000000 записей вместо того чтобы поэлементно очищать поле перебором:)

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

Во-вторых, все-таки нужно думать о тех, кто будет работать после нас.

А вот тут заминочка :) Если я пришел к клиенту - я решаю задачу так, как я считаю нужным - главное результат. И если я решил ее делать скриптами напрямую к БД - то мне как то пофиг, что админы бараны, и когда лег сервак, они просто базу на другом подняли и скрипты со старого скуля не перенесли.
Честно. Просто меня вызовут еще раз, я возьму еще раз деньги за эту работу, админы получат по шапке, что не ведут "журнал переноса", куда они должны писать всю последовательность действий, и все будут довольны :)

Это я к чему - если ориентироваться на людей, которые не способны изучать новое и пользоваться гуглом -то это лично их проблемы. Чего я, или клиент, должны страдать?
41. Дмитрий Шерстобитов (DitriX) 27.11.13 18:58
(39) а шо? вроде наоборот - все вышло куда круче :)
42. DAnry (DAnry) 27.11.13 19:13
Спасибо. Интересная и познавательная статья.
43. Ivan Kovtun (i.kovtun) 27.11.13 20:27
(40) DitriX,
Давайте еще раз - СОАП - это протокол ПЕРЕДАЧИ данных, а не ПОЛУЧЕНИЯ :) Что бы что то передать - это надо где то взять.

и все таки протокол обмена... Да идея SOAP никакого отношения к извлечению данных из системы не имеет. Тут 3 принципиальных момента:
1. Описание данных в терминах, которые отвязаны (могут быть отвязаны) от терминов приемника и передатчика. Данные упаковываем в XML файл.
2. Универсальное определение для типов данных, понятное для приемника и передатчика. Схема данных ссылается на базовые типы и определяет структуру данных.
3. Встроенные механизмы для валидации данных. При загрузке данных всегда проверяем соответствие правилам, определенных в схеме.
В результате обмен становится удобным, прозрачным и надежным. Но не всегда быстрым:)))
44. Дмитрий Шерстобитов (DitriX) 27.11.13 22:21
(43) если вам эта тема так интересна, то можете почитать мои статьи, в каждой из которых - я в том или ином вид использую соап протокол :)
45. Василий Казьмин (awk) 27.11.13 23:48
(32) Evgen.Ponomarenko,
Анализ степени фрагментации индексов при работе с MS SQL Server 2005

Обновлено: 15.11.2007

Чрезмерная фрагментация индексов создает проблемы для больших операций ввода-вывода. В MS SQL Server 2005 появились новые средства для контроля этого параметра.

Функция таблицы динамического управления sys.dm_db_index_physical_stats возвращает процент фрагментации в столбце avg_fragmentation_in_percent. Если значение в этом столбце превышает 25%, то для восстановления исходных параметров производительности рекомендуется выполнить дефрагментацию этого индекса. От снижения фрагментации индексов могут выиграть операции сканирования больших диапазонов данных, обычные в приложениях хранилищ данных и отчетов.

Использование этой информации может существенно снизить нагрузку на систему и избежать ненужных операций по дефрагментации тех индексов, для которых она не требуется.


Читай внимательно ИТС. Это первое упоминание, которое мне попалось.
46. Вячеслав Гилёв (Gilev.Vyacheslav) 27.11.13 23:57
чем прочитать чужое легче свое написать )))
47. Дмитрий Шерстобитов (DitriX) 28.11.13 00:48
(45) ваше сообщение не противоречит (32), вы это сообщение можете отправить к (17). Где человек отстаивает честь и достоинство ТиИ :)
(32) - это следствие (18), и попутный сарказм на тему того, что можно использовать ТОЛЬКО документированные функции. Т.е., если взять все дословно и включить режим зануды [читай - юриста], то то, что написали вы - можно использовать, а вот малейший шаг в сторону (т.е. если мы добавим там параметр или еще чего) - это уже будет отступ от лицензии.
Ну и к тому же - там не сказано явно, что это можно исправить средствами скуля. Т.е. продолжая мысль дальше - вы получили инфу, по разрешенной от 1С методике, а теперь - врубаем ТиИ, если он это вылечит, а если нет, то что тогда делать?

И кстати, как я писал в (18):
Нельзя обращаться к данным информационной базы напрямую, минуя уровень объектов работы с данными "1С:Предприятия" - например при помощи средств СУБД или при помощи внешних компонент, которые реализуют прямой доступ к СУБД. Это ограничение распространяется на любые действия с данными, в том числе на изменение их структуры, а так же на чтение или изменение самих данных информационной базы или служебных данных "1С:Предприятия".

Тут сказано, что тупо ВСЕ запрещено. Так что,если вы будете использовать тот метод получения индексов, то вы нарушаете лицензионное соглашение :)

З.Ы. Это уже идет чисто стеб, не ищите истины в словах выше. ИМХО.
48. Дмитрий Шерстобитов (DitriX) 28.11.13 00:51
(46) и Вам добрый вечер. Я вот знаю что вы в этой теме - один из первых (я про 1С +/- скуль, в частности). Сам у вас одно время помощи искал, и, надо отдать должное, таки нашел :)

Интересно ваше мнение на все эти ситуации. Как вы считаете - 1С реально забило болт на это все, и просто не обновляет лицензионное соглашение? (ну оно понятно, что это затея весьма трудозатратна)
Или же реально были случаи разбирательств по данному поводу?
ixilimuse; +1 Ответить
49. Евгений Пономаренко (Evgen.Ponomarenko) 28.11.13 11:46
(45) awk,
Лично у меня чтение третесортной документации и еже с ней таких же лицензионных соглашений вызывает
сильнейший когнитивный диссонанс, который иногда выливается в откровенный стЁб.
Честно говоря лицензионное соглашение от 1с не проходит испытание даже "легкого включения" формальной логики.

И все же попробую компильнуть размытые формулировки 1С в более-менее "машинный код":

ПРОГРАММНЫЙ ПРОДУКТ – это комплект поставки "1С:Предприятия 8", в состав которого в числе прочего входит дистрибутив платформы "1С:Предприятие 8", дистрибутив по крайней мере одного прикладного решения или конфигурации (кроме отдельных поставок "1С:Предприятия 8") и Лицензионное соглашение, регулирующее правила использования ПРОГРАММНОГО ПРОДУКТА.

4. Лицензиат обязуется не допускать нарушений исключительных прав Правообладателя на ПРОГРАММНЫЙ ПРОДУКТ, в частности, не совершать и не допускать совершения третьими лицами следующих действий без специального письменного разрешения Правообладателя:

вносить какие-либо изменения в код ПРОГРАММНОГО ПРОДУКТА, содержимое баз данных и других наборов данных, в которых система хранит информацию, за исключением тех изменений, которые вносятся штатными средствами, входящими в состав ПРОГРАММНОГО ПРОДУКТА и описанными в сопроводительной документации;

осуществлять доступ к информационной базе ПРОГРАММНОГО ПРОДУКТА и построение систем на основе ПРОГРАММНОГО ПРОДУКТА с помощью средств и технологических решений, не предусмотренных в сопроводительной документации;

Нельзя обращаться к данным информационной базы напрямую, минуя уровень объектов работы с данными "1С:Предприятия" - например при помощи средств СУБД или при помощи внешних компонент, которые реализуют прямой доступ к СУБД. Это ограничение распространяется на любые действия с данными, в том числе на изменение их структуры, а так же на чтение или изменение самих данных информационной базы или служебных данных "1С:Предприятия".

Следует использовать метод только для административных задач обслуживания базы данных и анализа записей технологического журнала. Не следует применять метод для реализации какой-либо части прикладной функциональности.

ИТАК:
Нельзя обращаться к данным информационной базы ПРОГРАММНОГО ПРОДУКТА напрямую минуя уровень объектов работы с данными "1С:Предприятия" - например при помощи средств СУБД или при помощи внешних компонент, которые реализуют прямой доступ к СУБД.
Это ограничение распространяется на любые действия с данными, в том числе на изменение их структуры, а так же на чтение или изменение самих данных информационной базы или служебных данных "1С:Предприятия", кроме
случаев решения административных задач обслуживания базы данных и анализа записей технологического журнала.
Если средства и технологические решения описаны в сопроводительной документации (в том числе на дисках ИТС) такой доступ считается лицензионным.

Выводы:
1. В лицензионном соглашении не описаны определения "средств" и "технологические решения", что дает широчайшую свободу для толкования, над чем мы вчера цинично поглумились.
2. Ваш пост (45) цитирует сопроводительную документацию (диск ИТС), а значит конкретный метод можно считать лицензионным. Однако обратное доказать с помощью той же сопроводительной документации не удается,
так как все, что не описано в документации - "запрещено"
3. Ваш пост (45) совершенно не относится к данной теме, так как объект sys.dm_db_index_physical_stats не входит в состав ПРОГРАММНОГО ПРОДУКТА, а входит в состав дистрибутива MSSQL.
4. Факт чтения данных информационной базы третими инстументами доказать не возможно, кроме случая когда третье лицо сам сдаст лицензиата.

PS Честно, говоря я не любитель чтения-перечтения ИТС. Если у меня возникают технологические проблемы с производительностью СУБД, я обращаюсь фирменной к документации по СУБД.

Читай внимательно ИТС. Это первое упоминание, которое мне попалось.

Фраза достойная желтой карточки - полезной информации ноль, плюс примитивный посыл к документации.
Вы случайно разноской ИТС не занимались?
chemezov; DitriX; +2 Ответить
50. Евгений Мукомело (ixilimuse) 28.11.13 13:56
Дорогие друзья и коллеги!
Спасибо всем вам, за весьма интересное обсуждение :)
Я искренне прошу прощения у всех, кто зря потерял время на прочтение этой публикации.

Я не из тех кто рекламирует использование прямых запросов везде где можно и не нужно. Мне просто повезло что в свое время я столкнулся с задачей где это реально было актуально. Более с тех пор, подобных задач - не встречал.

Примерно год или даже чуть больше назад я работал над этой задачей. Тогда это была одна из первых моих задач на 1С. Ибо я только-только перешел в эту сферу. И на момент решения я собирал описанную здесь информацию по крупицам из разных источников. Так и родилась идея написать эту статью. Написать написал.. Но публиковать не решался. Затем черновые варианты публиковал на Хабре. Потом убрал их от туда. Внес ещё ряд корректив и вот решился запостить здесь, спустя столько времени. И то лишь потому что находились люди которые писали мне письма с вопросом, почему я убрал все первые публикации этой темы. Интересовались будут ли репосты. Вероятно это начинающие спецы. Поэтому если эта статья окажется полезной хотя бы пяти людям, я буду рад. Но я не претендую на высокую оценку этого материала, ибо это лишь описание тех вещей, которые мне самому были не понятны на первых этапах познания 1С платформы.

(46) Gilev.Vyacheslav, Вам отдельное спасибо за ваши статьи и материалы. А так же за видео уроки по теме 1С :)
Evgen.Ponomarenko; +1 Ответить 2
51. Евгений Пономаренко (Evgen.Ponomarenko) 28.11.13 14:37
(50) ixilimuse,
Мне близка ваша позиция.
В 2007 мне пришлось подружить Oracle 8i и 1С...
К сожалению я тогда не знал о существовании ИС... и по тому все наработки слегли в архив.

К стати, к вопросу производительности:
Делали в 2010 году экспертную систему для подбора автозапчастей на стартеры/генераторы.
Когда мы выжали из 1С все, что можно и не можно, то часть данных вынесли в MySQL.
Получили выигрышь в производительности в 20-30 раз по сравнению с MSSQL.
К тому же, эту же структуру хранения использовали для интеграции с веб-сайтом.
Так, что статья вышла очень полезная!
ixilimuse; +1 Ответить
52. Ivan Kovtun (i.kovtun) 28.11.13 14:56
(44) DitriX, Спасибо, предпочитаю первоисточники.
53. Серж М (tim11.06) 28.11.13 15:05
(50) ixilimuse, мне пришлось Firebeard c 1С сдруживать причем в этом году. Искренне нам сочувствую
54. Александр Кузин (sashocq) 28.11.13 15:31
Интересующимся темой советую обратить внимание на эту обработку: http://infostart.ru/public/118593/
Она может создать в БД вьюхи с человеческими именами. Для себя я к ней немножко еще подкрутил функции преобразования ссылок в гуиды и binary(1) в int.
sashapere; DitriX; +2 Ответить
55. Maxim Kolkin (the1) 02.12.13 14:09
Народ, у меня небольшой оффтоп. А объект "Интерфейс" (например, Общие//Интерфейсф//Полный) имеет какой-либо ГУИД в базе?
56. Alex Gaiduk (AlexSunS) 17.12.13 09:48
(53) tim11.06, Исправьтесь пожалуйста...
57. Серж М (tim11.06) 17.12.13 11:35
(56) AlexSunS, Куда исправится??
58. poyson (poyson) 08.05.14 14:14
Спасибо за подробный пример. Клепали нечто подробное на 7.7. - там по другому никак. В 8 пока не сталкивались...
59. kiruha Дронов (kiruha) 08.05.14 16:10
По поводу лицензионности - как то консультировался со штатными юристами.

Если MS SQL куплен/используется законно - все инструменты входящие в пакет SQL использовать абсолютно законно.Без каких либо ограничений (сопровождение или еще что)
В любом случае это дело Вас и Микрософта - 1C может только снять с себя ответственность за работоспособность Вашей базы.
Думаю , что юристы 1С это прекрасно знают , поэтому комментарии их всегда были невнятными и более напоминали "страшилки"
AlexanderKai; jan27; +2 Ответить
60. andrey dyak (dyak84) 30.01.15 12:48
Автору спасибо при больших обэмах даных начинаеш задумыватся что и скуль надо подучить. Статья интересная для общего представления.