При работе с базами данных 1С на уровне SQL Server программисты часто сталкиваются с полем Version (или _Version). На первый взгляд может показаться, что это поле хранит дату последнего изменения объекта, зашифрованную в каком-то специфическом формате. Однако попытки перевести эти данные в понятный формат даты и времени часто приводят к путанице. В этой статье мы разберем природу этого поля, выясним, как оно формируется, и почему его невозможно превратить в дату.
Рассмотрим ситуацию: при анализе таблицы документа в SQL мы видим колонку Version с типом данных timestamp (в новых версиях SQL Server он называется rowversion). Значения в нем выглядят как шестнадцатеричные числа, например, 0x0000000000263CED. Проанализируем основные заблуждения, связанные с этим полем:
На самом деле, тип данных rowversion в MS SQL Server никак не связан с системными часами. Это просто 8-байтовое двоичное число, которое увеличивается внутри конкретной базы данных при каждой операции вставки или обновления строки. Выясним, как именно это работает.
Разберем по шагам, что происходит в базе данных, когда мы записываем документ:
@@DBTS).rowversion, этот счетчик увеличивается на единицу.Version изменяемой строки.Таким образом, это поле гарантирует уникальность в пределах всей базы данных. Если вы измените один документ, а затем другой, версия второго документа будет гарантированно больше версии первого. Однако разница между этими значениями не скажет вам, сколько времени прошло между операциями — секунда или месяц. Посмотрим на этот механизм как на порядковый номер изменения состояния всей базы.
Проанализируем ситуацию: два пользователя одновременно открыли один и тот же документ. Платформа 1С должна гарантировать, что один пользователь не перезапишет изменения другого незаметно. Для этого используется механизм оптимистической блокировки, опирающийся на поле Version:
Version.Version в базе увеличилось. Проверка не пройдет, и 1С выдаст ошибку: «Объект изменен или удален другим пользователем».Как мы уже выяснили, прямой математической связи между числом 0x0000000000263CED и временем записи не существует. Поле Version не хранит время. Единственное, что можно сделать — это сравнивать версии между собой, чтобы понять, какой объект был изменен позже.
Тем не менее, в 1С иногда возникает необходимость работать с реальными Unix Timestamp (метками времени в секундах от 1970 года), например, при интеграции со сторонними веб-сервисами. Чтобы не путать их с системным полем Version, рассмотрим пример функций для преобразования обычной даты 1С в Unix-timestamp и обратно:
Функция ДатуВTimestamp(пДата = Неопределено) Экспорт
Если пДата = Неопределено Тогда
пДата = ТекущаяДата();
КонецЕсли;
// Вычисляем разницу в секундах между датой и началом эпохи Unix
Возврат Формат(Число(пДата - Дата("19700101")), "ЧН=0; ЧГ=0");
КонецФункции
Функция TimestampВДату(пДатаТС) Экспорт
Попытка
// Прибавляем количество секунд к дате начала эпохи
Возврат Дата("19700101") + ?(ТипЗнч(пДатаТС) = Тип("Строка"), Число(пДатаТС), пДатаТС);
Исключение
Возврат Неопределено;
КонецПопытки;
КонецФункции
Важно: Эти функции полезны для работы с API (например, REST), но они не помогут расшифровать поле _Version из SQL-таблицы 1С.
В современных версиях платформы (8.3.x и выше) поле Version нашло дополнительные применения. Проанализируем их:
Разберем ключевые выводы нашего анализа:
Version — это технический счетчик SQL Server типа rowversion.Понимание работы этого механизма помогает лучше разобраться в том, как 1С взаимодействует с СУБД и почему возникают ошибки конкурентного доступа к данным. Помните, что для отслеживания времени изменений объектов в 1С следует использовать стандартный механизм Версионирования объектов (История данных), который сохраняет реальную дату и время каждого изменения в отдельных служебных таблицах.