Преобразование типов данных
Доступно, начиная с версии DaJet 3.11.3
- Простой типовой пример пребобразования типа
- Обработка значений составного типа в запросах
- Преобразование составного типа данных
union - Пример работы с датами
- Изменение и сравнение дат
- Анализ типа данных регистратора
- Анализ типа узла таблицы регистрации изменений плана обмена
- Пример создания документа с табличной частью
Преобразование типов данных выполняется в DaJet Script при помощи функции CAST, аналогично стандартному синтаксису SQL. Функция возвращает значение, указанного после ключевого слова AS, типа данных. Преобразование выполняется согласно нижеследующей таблице приводимости типов данных.
CAST(<expression> AS <target_type>)
Подробная информация о системе типов данных DaJet Script
<expression> - выражение DaJet Script, обычно переменная или обращение к свойству объекта.
<target_type> - тип данных, к которому необходимо привести значение выражения. Допустимые значения:
booleaninteger(целое число)decimal(синоним дляnumber)datetimestringbinaryuuidentity
Таблица преобразования типов данных
В колонке “Тип данных” указан исходный тип данных. Заголовки последующих колонок указывают на целевой тип данных, к которому можно преобразовать значение исходного типа данных. В ячейках пересечения указывается возможность такого преобразования, формат получаемого значения. Если ячейка не заполнена, то выполненеие преобразования типа невозможно.
| Тип данных |
union | boolean | integer | decimal | datetime | string | entity | uuid | binary |
|---|---|---|---|---|---|---|---|---|---|
| union | + | + | + | + | + | + | |||
| boolean | 1 или 0 | “true” “false” |
0x01 0x00 |
||||||
| integer | true != 0 false == 0 |
+ | Секунды от 01.01.0001 |
+ | big endian |
||||
| decimal | Целая часть без округления |
+ | |||||||
| datetime | Секунды от 01.01.0001 |
ISO-8601 | |||||||
| string | true false |
+ | + | ISO-8601 | + | + | UTF-8 | ||
| entity | {int:uuid} | ||||||||
| uuid | + | + | |||||||
| binary | true false |
big endian |
UTF-8 | + |
Подробная информация о других функциях анализа типов данных DaJet Script
Тип данных
stringявляется универсальным типом данных в том смысле, что любой другой тип данных может быть выражен через него и преобразован обратно. Кроме этого следует иметь ввиду, что многие типы данных имеют в DaJet Script специальные литералы, которые преобразуются парсером языка в целевой тип автоматически.
Простой типовой пример пребобразования типа integer
DECLARE @object object
DECLARE @integer integer
SET @integer = 16
MODIFY @object
SELECT Boolean = CAST(@integer AS boolean)
, Decimal = CAST(@integer AS decimal)
, DateTime = CAST(@integer AS datetime)
, String = CAST(@integer AS string)
, Binary = CAST(@integer AS binary)
, Binary1 = CAST(@integer AS binary(1)) -- берётся младший байт из 4-х
RETURN @object
Пример работы с датами
В данном примере полезно познакомиться с таким понятием, как квалификаторы типов данных. В данном случае используется квалификатор типа данных integer, который принудительно устанавливает его размер равным 8 байтам. По умолчанию этот размер равен 4 байтам. В данном случае это необходимо, так как выражение даты в виде числа (количества секунд) выполняется при помощи больших чисел.
DECLARE @object object
DECLARE @datetime datetime
DECLARE @seconds integer(8)
SET @datetime = CAST(59 AS datetime)
SET @seconds = CAST(@datetime AS integer)
SET @seconds = @seconds + 3600
MODIFY @object
SELECT Integer = @seconds
, String = CAST(@datetime AS string)
, DateTime = CAST(@seconds AS datetime)
RETURN @object
Изменение и сравнение дат
В данном примере показано как при помощи функционала преобразования типов данных можно выполнять, недоступные штатными средствами DaJet Script, операции изменения и сравнения дат.
DECLARE @object object
DECLARE @НачалоПериода datetime
DECLARE @КонецПериода datetime
DECLARE @НачалоВСекундах integer(8)
DECLARE @КонецВСекундах integer(8)
SET @НачалоПериода = '2000-01-01 12:00:00'
SET @КонецПериода = '2000-01-01 12:00:00'
SET @НачалоВСекундах = CAST(@НачалоПериода AS integer)
SET @КонецВСекундах = CAST(@КонецПериода AS integer)
MODIFY @object
SELECT НачалоПериода = @НачалоПериода
, КонецПериода = @КонецПериода
, НачалоВСекундах = @НачалоВСекундах
, КонецВСекундах = @КонецВСекундах
, Результат = CASE
WHEN @НачалоВСекундах > @КонецВСекундах THEN 'начало больше'
WHEN @НачалоВСекундах < @КонецВСекундах THEN 'начало меньше'
WHEN @НачалоВСекундах = @КонецВСекундах THEN 'начало и конец равны'
END
RETURN @object
Преобразование составного типа данных union
В данном примере важно обратить внимание на то, что преобразование составного типа данных union будет успешно выполняться только в том случае, когда конкретное значение union содержит целевой тип данных. В противном случае будет выдана ошибка. Таким образом, предварительно выполняется анализ значения union на содержащийся в нём тип данных при помощи функции TYPEOF.
DEFINE Запись(Код string, ПолныйСоставнойТип union)
DECLARE @array array OF Запись
DECLARE @object object
DECLARE @type string
DECLARE @union union
USE 'mssql://server/database'
SELECT Код, ПолныйСоставнойТип INTO @array FROM Справочник.Тестовый ORDER BY Код ASC
END --USE
FOR @object IN @array
SET @union = @object.ПолныйСоставнойТип
SET @type = TYPEOF(@object.ПолныйСоставнойТип)
MODIFY @object DELETE ПолныйСоставнойТип
SELECT ТипДанных = @type, Значение = CASE
WHEN @type = TYPEOF(boolean) THEN CAST(CAST(@union AS boolean) AS string)
WHEN @type = TYPEOF(number) THEN CAST(CAST(@union AS decimal) AS string) -- CAST(@union AS integer)
WHEN @type = TYPEOF(datetime) THEN CAST(CAST(@union AS datetime) AS string)
WHEN @type = TYPEOF(string) THEN CAST(CAST(@union AS string) AS string)
WHEN @type = TYPEOF(entity) THEN CAST(CAST(@union AS entity) AS string)
ELSE 'Неопределено' END --CASE
END --FOR
RETURN @array
Анализ типа данных регистратора
В данном примере для анализа типа данных регистратора используется вспомогательная переменная СсылкаРегистратора. Несмотря на то, что тип данных поля регистра накопления Регистратор чаще всего имеет составной тип данных union, исторически так сложилось, что DaJet, оптимизируя работу с базой данных, загружает такие значения как тип данных entity. Таким образом это приводит к конфликту между логикой загрузки значений из базы данных и новым функционалом DaJet Script при поиске функции TYPEOF, NAMEOF или CAST с нужной сигнатурой (эти функции перегружены и имеют несколько вариантов использования в зависимости от типа данных входных параметров).
DECLARE @НаборЗаписей array
DECLARE @ЗаписьРегистра object
DECLARE @ТипРегистратора string
DECLARE @СсылкаРегистратора entity
USE 'mssql://server/database'
SELECT ВидДвижения, Регистратор
, Номенклатура, Количество
INTO @НаборЗаписей
FROM РегистрНакопления.ЗапасыНаСкладах
FOR @ЗаписьРегистра IN @НаборЗаписей
SET @СсылкаРегистратора = @ЗаписьРегистра.Регистратор
SET @ТипРегистратора = NAMEOF(@СсылкаРегистратора)
MODIFY @ЗаписьРегистра
SELECT ТипДокумента = @ТипРегистратора
END
END
RETURN @НаборЗаписей
Анализ типа узла таблицы регистрации изменений плана обмена
Данный пример аналогичен анализу типа данных регистратора. Объяснение использования вспомогательной переменной здесь такое же.
DEFINE Запись(УзелОбмена union, Ссылка entity)
DECLARE @array array OF Запись
DECLARE @object object
DECLARE @entity entity
DECLARE @ИмяПланаОбмена string
USE 'mssql://server/database'
SELECT УзелОбмена, Ссылка INTO @array
FROM Справочник.Тестовый.Изменения
FOR @object IN @array
SET @entity = @object.УзелОбмена
SET @ИмяПланаОбмена = NAMEOF(@entity)
MODIFY @object
SELECT ТипПланаОбмена = TYPEOF(@entity)
, ИмяПланаОбмена = @ИмяПланаОбмена
END --FOR
END --USE
RETURN @array
Пример создания документа с табличной частью
Данный пример, прежде всего, интересен способом работы с табличной частью документа. Используется преобразование значения типа integer в binary. Это необходимо, так как некоторые служебные поля таблиц базы данных 1С:Предприятие 8 имеют бинарный тип данных.
DECLARE @ДокументСсылка uuid
DECLARE @НоменклатураСсылка uuid
DECLARE @КлючСтроки binary
DECLARE @НомерСтроки decimal
DECLARE @ДатаДокумента datetime
DECLARE @НомерДокумента string
DECLARE @КоличествоСтрок integer
DECLARE @КоличествоДокументов integer
PRINT 'Начало'
USE 'mssql://server/database'
SELECT TOP 1 Ссылка = UUIDOF(Ссылка)
INTO @НоменклатураСсылка
FROM Справочник.Номенклатура
WHERE Код = '000000001'
SET @КоличествоДокументов = 1
WHILE @КоличествоДокументов <= 1000
SET @ДатаДокумента = NOW(0)
SET @ДокументСсылка = NEWUUID()
SET @НомерДокумента = CAST(@КоличествоДокументов AS string)
INSERT Документ.УстановкаЦен
SELECT Ссылка = @ДокументСсылка
, Дата = @ДатаДокумента
, Номер = @НомерДокумента
, Проведён = FALSE
, ПометкаУдаления = FALSE
SET @КоличествоСтрок = 1
WHILE @КоличествоСтрок <= 10
SET @КлючСтроки = CAST(@КоличествоСтрок AS binary)
SET @НомерСтроки = CAST(@КоличествоСтрок AS decimal)
INSERT Документ.УстановкаЦен.Товары
SELECT Ссылка = @ДокументСсылка
, KeyField = @КлючСтроки
, НомерСтроки = @НомерСтроки
, Номенклатура = @НоменклатураСсылка
, Цена = 1.00
SET @КоличествоСтрок = @КоличествоСтрок + 1
END
SET @КоличествоДокументов = @КоличествоДокументов + 1
END
END
PRINT 'Конец'
Обработка значений составного типа в запросах
Следующий пример демонстрирует использование функций TYPEOF и CAST в целях обработки значений составного типа в запросах DaJet. При этом следует иметь в виду, что реализация функции CAST в запросах узко специализированна. Она должна использоваться только для извлечения значений соответствующих полей.
В случае, если будет предпринята попытка получить значение типа данных, который не настроен в качестве допустимого значения для соответствующего поля составного типа в конфигураторе 1С:Предприятие, будет выдана ошибка, например, следующего вида:
[CAST] type column [boolean] is not found
Предупредить ошибку можно, используя функцию CAST в сочетании с функцией TYPEOF.
На заметку! Для получения значений типа
entityможно использовать функцию UUIDOF.
DECLARE @table array
USE 'mssql://server/database'
SELECT КодТипа = TYPEOF(ПолныйСоставнойТип) -- _Fld_TYPE или _Fld_RTRef
, ИмяТипа = CASE
WHEN TYPEOF(ПолныйСоставнойТип) = TYPEOF(boolean) THEN 'boolean'
WHEN TYPEOF(ПолныйСоставнойТип) = TYPEOF(number) THEN 'number'
WHEN TYPEOF(ПолныйСоставнойТип) = TYPEOF(datetime) THEN 'datetime'
WHEN TYPEOF(ПолныйСоставнойТип) = TYPEOF(string) THEN 'string'
WHEN TYPEOF(ПолныйСоставнойТип) > TYPEOF(entity) THEN 'entity'
ELSE 'Неопределено' END --CASE
, Булево = CAST(ПолныйСоставнойТип AS boolean) -- _Fld_L
, Число = CAST(ПолныйСоставнойТип AS number) -- _Fld_N
, ДатаВремя = CAST(ПолныйСоставнойТип AS datetime) -- _Fld_T
, Строка = CAST(ПолныйСоставнойТип AS string) -- _Fld_S
, Ссылка = CAST(ПолныйСоставнойТип AS entity) -- _Fld_RRRef
INTO @table
FROM Справочник.Тестовый ORDER BY Код ASC
END -- USE
RETURN @table
Результат выполнения запроса
| КодТипа | ИмяТипа | Булево | Число | ДатаВремя | Строка | Ссылка |
|---|---|---|---|---|---|---|
| 2 | boolean | True | 0.00 | 01/01/0001 00:00:00 | 00000000-0000-0000-0000-000000000000 | |
| 3 | number | False | 123.45 | 01/01/0001 00:00:00 | 00000000-0000-0000-0000-000000000000 | |
| 4 | datetime | False | 0.00 | 26/06/2025 00:00:00 | 00000000-0000-0000-0000-000000000000 | |
| 5 | string | False | 0.00 | 01/01/0001 00:00:00 | это строка | 00000000-0000-0000-0000-000000000000 |
| 137 | entity | False | 0.00 | 01/01/0001 00:00:00 | 643c4d9d-cacf-4048-11f0-485f1e777c9a | |
| 138 | entity | False | 0.00 | 01/01/0001 00:00:00 | 643c4e9d-cacf-4048-11f0-5a757b194e12 | |
| 138 | entity | False | 0.00 | 01/01/0001 00:00:00 | 00000000-0000-0000-0000-000000000000 | |
| 1 | Неопределено | False | 0.00 | 01/01/0001 00:00:00 | 00000000-0000-0000-0000-000000000000 |