Преобразование типов данных
Доступно, начиная с версии DaJet 3.11.3
- Простой типовой пример пребобразования типа
- Обработка значений составного типа в запросах
- Преобразование составного типа данных
union
- Пример работы с датами
- Изменение и сравнение дат
- Анализ типа данных регистратора
- Анализ типа узла таблицы регистрации изменений плана обмена
- Пример создания документа с табличной частью
Преобразование типов данных выполняется в DaJet Script при помощи функции CAST
, аналогично стандартному синтаксису SQL. Функция возвращает значение, указанного после ключевого слова AS, типа данных. Преобразование выполняется согласно нижеследующей таблице приводимости типов данных.
CAST(<expression> AS <target_type>)
Подробная информация о системе типов данных DaJet Script
<expression> - выражение DaJet Script, обычно переменная или обращение к свойству объекта.
<target_type> - тип данных, к которому необходимо привести значение выражения. Допустимые значения:
boolean
integer
(целое число)decimal
(синоним дляnumber
)datetime
string
binary
uuid
entity
Таблица преобразования типов данных
В колонке “Тип данных” указан исходный тип данных. Заголовки последующих колонок указывают на целевой тип данных, к которому можно преобразовать значение исходного типа данных. В ячейках пересечения указывается возможность такого преобразования, формат получаемого значения. Если ячейка не заполнена, то выполненеие преобразования типа невозможно.
Тип данных |
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 |