Имя: Пароль:
1C
 
Поведение ЕСТЬNULL()
0 luter-89
 
01.12.16
16:14
Сегодня обратил внимание на странное поведение оператора ЕСТЬNULL().
Пример:

Длина кода справочника - 9 символов.

Естьnull(Сотрудники.Код,"9999999999999999999999999999")
вернет - "999999999"

Получается Естьnull еще и длину строки устанавливает.

Пришлось обходить через ВЫБОР КОГДА.

Кто-нибудь сталкивался с таким поведением, странно, что раньше не замечал
1 DrShad
 
01.12.16
16:18
сталкивались конечно

НайтиПоНаименованию(NULL) вернет первую попавшуюся ссылку
2 RomanYS
 
01.12.16
16:18
Естьnull не приводит типы, где-то в коде это сделал.
3 RomanYS
 
01.12.16
16:21
(1) в чем вопрос? ты неявно привел null к пустой строке и по ней ищешь - получишь первую попавшуюся. Укажи второй параметр (ТочноеСовпадение = Истина) и не получишь ничего
4 Fragster
 
гуру
01.12.16
16:23
https://msdn.microsoft.com/ru-ru/library/ms184325.aspx

Возвращает тот же тип, что и аргумент check_expression. Если литерал NULL указывается в качестве check_expression, возвращает тип данных значения replacement_value. Если литерал NULL указывается в качестве check_expression и не указано никакого значения replacement_value, возвращает int.
5 Fragster
 
гуру
01.12.16
16:24
Заметки

Значение аргумента check_expression возвращается в случае, если оно не равно NULL. В противном случае возвращается значение аргумента replacement_value, после того как это значение будет неявно преобразовано к типу значения аргумента check_expression, если типы различаются. replacement_value может быть усечено, если длина replacement_value превышает check_expression.
6 Fragster
 
гуру
01.12.16
16:25
короче, это фича
7 NafNaf2000
 
01.12.16
16:27
ВЫБРАТЬ
    ВложенныйЗапрос.Ф,
    ЕСТЬNULL(Валюты.Код,"99999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999")
ИЗ
    (ВЫБРАТЬ
        1 КАК Ф) КАК ВложенныйЗапрос
        ЛЕВОЕ СОЕДИНЕНИЕ Справочник.Валюты КАК Валюты
        ПО ВложенныйЗапрос.Ф ЕСТЬ NULL

выдает:

Ф    Поле 1
1    99999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999
8 RomanYS
 
01.12.16
16:29
http://savepic.net/8625410.htm
(6) у меня нет такой фичи
платформа 8.3.5 на MSSQL
9 Fragster
 
гуру
01.12.16
16:39
(7)(8) так то на файловой
10 Fragster
 
гуру
01.12.16
16:39
можете, кстати, багу открыть на v8, чтобы 1с это поправило
11 Cool_Profi
 
01.12.16
16:40
(9) На серверной 8.2.19 ничего не обрезается
12 Fragster
 
гуру
01.12.16
16:40
(11) с мсскуль?
13 Cool_Profi
 
01.12.16
16:40
(12) да
14 RomanYS
 
01.12.16
16:43
(9) в (8) тоже MSSQL
15 RomanYS
 
01.12.16
16:47
(5) в 1С похоже своя реализация ЕстьNULL. Иногда использую такие конструкции ЕстьNULL(Остатки.Количество, "нет остатка") и никогда не сталкивался здесь с приведением типов.
16 DrShad
 
01.12.16
16:49
так тут типы различаются
17 mehfk
 
01.12.16
16:51
(7) Преобразуется в
exec sp_executesql N'SELECT
T1.Q_001_F_000_,
ISNULL(CAST(T2._Code AS NVARCHAR(95)),@P1)
FROM (SELECTн.
1.0 AS Q_001_F_000_) T1
LEFT OUTER JOIN dbo._Reference7 T2 WITH(NOLOCK)
ON T1.Q_001_F_000_ IS NULL', N'@P1 nvarchar(4000)', N'99999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999'
результат очевиде
18 luter-89
 
01.12.16
16:53
Платформа 8.3.9.1850
19 mehfk
 
01.12.16
16:54
(17)+ Платформа 8.3.6.2449
20 mehfk
 
01.12.16
17:00
А на 8.3.8.2088

SELECT
T1.Q_001_F_000_,
ISNULL(T2._Code,@P1)
FROM (SELECT
1.0 AS Q_001_F_000_) T1
LEFT OUTER JOIN dbo._Reference70 T2 WITH(NOLOCK)
ON T1.Q_001_F_000_ IS NULL',N'@P1 nvarchar(4000)',N'99999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999'

И там и там режим совместимости 8.2.16
21 Fragster
 
гуру
01.12.16
17:02
(20) а если разные типы (например число и строку) в естьнулл запихнуть? или, там, ссылку?
22 mehfk
 
01.12.16
17:05
(21) Если "99999..." заменить на число - то генерится CASE WHEN на 8.3.6
23 mehfk
 
01.12.16
17:08
на 8.3.8 то же самое.

exec sp_executesql N'SELECT
T1.Q_001_F_000_,
CASE WHEN T2._Code IS NULL THEN 0x03 ELSE CASE WHEN T2._Code IS NOT NULL THEN 0x05 END END,
CASE WHEN T2._Code IS NULL THEN 100500.0 ELSE CASE WHEN T2._Code IS NOT NULL THEN 0.0 END END,
CASE WHEN T2._Code IS NULL THEN P1 ELSE T2._Code END
FROM (SELECT
1.0 AS Q_001_F_000_) T1
LEFT OUTER JOIN dbo._Reference70 T2 WITH(NOLOCK)
ON T1.Q_001_F_000_ IS NULL',N'P1 nvarchar(4000)',N''

Вообще интересная фишка,результат запроса еще дополнительно обрабатывается.
24 HEKPOH
 
01.12.16
17:15
(2) "Естьnull не приводит типы"
приводит
25 HEKPOH
 
01.12.16
17:16
(0)
Функция ЕСТЬNULL() хоть и является аналогом операции ВЫБРАТЬ с проверкой значения на NULL, тем не менее, имеет отличие. Отличие заключается в том, что в случае, если выражение функции имеет строковой или числовой тип, то выражение замены будет преобразовано к типу проверяемого выражения.

http://its.1c.ru/db/metod8dev#content:2653:hdoc
26 NafNaf2000
 
01.12.16
17:18
(9) MSSQL
27 RomanYS
 
01.12.16
17:22
(25) да, написано одно, а работает по другому. Попробовал в (8) явно задать тип     ЕСТЬNULL(Выразить(Сотрудники.Код как Строка(10)), "9999999999999999999999999999"), результат тот же - не обрезает
28 HEKPOH
 
01.12.16
17:40
(27) в моей практике такого не было, т.е. всегда обрезала