|
v8: Ошибка функции ЕСТЬNULL () в 8.2 | ☑ | ||
---|---|---|---|---|
0
vvp117
20.03.12
✎
13:33
|
Конфигурация: Зарплата и управление персоналом 8.2
Версия конфигурации: 2.5.47.1 Платформа: 8.2.14.519 Суть ошибки: функция ЕСТЬNULL() игнорирует значение с типом NULL в первом параметрею Вообще ошибка вот в таком коде: ВЫБРАТЬ ПЕРВЫЕ 100 ЕСТЬNULL(&Префикс + РО.ОбособленноеПодразделениеЗавершения.Код,"не указано") КАК П10 ИЗ РегистрСведений.РаботникиОрганизаций КАК РО ЛЕВОЕ СОЕДИНЕНИЕ Справочник.Организации КАК ОРГ ПО ОРГ.Ссылка = РО.ОбособленноеПодразделениеЗавершения Но проще ее увидеть в пустой конфигурации (я использовал основной режим конфигурации [Обычное приложение]). Создаем пустую конфигурацию с объектами: 1. Справочник [Сотрудники]. 2. Справочник [Организации] (тип кода, что ВАЖНО, - Строка). 3. Независимый непериодический регистр сведений [Документы] с измерением [Сотрудник] (тип: СправочникСсылка.Сотрудники) и ресурсом [Организация] (тип: СправочникСсылка.Организации). Запускаем режим [Предприятие] и добавляем в регистр одну запись, в которой заполняем поле [Сотрудник], а поле [Организация] оставляем пустым. Затем открываем консоль запросов/отчетов, кому как нравится, и выполняем следующий запрос: Запрос 1 ВЫБРАТЬ Доки.Организация.Код КАК ЧистыйКодОрганизации, (&Префикс + Доки.Организация.Код) КАК ПреобразованиеКNULL, ЕСТЬNULL(&Префикс + Доки.Организация.Код,"не указано") КАК КодОрганизации ИЗ РегистрСведений.Документы КАК Доки ЛЕВОЕ СОЕДИНЕНИЕ Справочник.Организация КАК ОРГ ПО ОРГ.Ссылка = Доки.Организация где: &Префикс = "СЗ" (это требуется для решения задачи) В результате имеем одну запись, в которой: ЧистыйКодОрганизации = NULL ПреобразованиеКNULL = NULL КодОрганизации = NULL Но если выполнить такой запрос: Запрос 2 ВЫБРАТЬ NULL КАК ЧистыйКодОрганизации, (&Префикс + NULL) КАК ПреобразованиеКNULL, ЕСТЬNULL(&Префикс + NULL,"не указано") КАК КодОрганизации ИЗ РегистрСведений.Документы КАК Доки ЛЕВОЕ СОЕДИНЕНИЕ Справочник.Организация КАК ОРГ ПО ОРГ.Ссылка = Доки.Организация То имеем запись со значениями полей: ЧистыйКодОрганизации = NULL ПреобразованиеКNULL = NULL КодОрганизации = "не указано" что собственно и требуется!!! ВОПРОС: в чем отличие работы запросов 1 и 2??? почему они дают различные результаты? может я чего то не понимаю? конечно, можно воспользоваться оператором ВЫБОР вот так: ВЫБОР КОГДА Доки.Организация.Код ЕСТЬ NULL ТОГДА "не указано" ИНАЧЕ &Префикс + Доки.Организация.Код КОНЕЦ КАК КодОрганизации но это не так красиво, т.к. выбирается много полей такого вида: ЕСТЬNULL(&Префикс + Доки.Организация.Код,"не указано") |
|||
1
le_
20.03.12
✎
13:38
|
ЕСТЬNULL(&Префикс + Доки.Организация.Код, "не указано") - как это это не правильно.
ИМХО, лучше так: Выбор Когда Доки.Организация.Код есть NULL Тогда
|
|||
2
vvp117
20.03.12
✎
13:42
|
ну так то оно так, но почему?
я и сам понимаю, что через оператор ВЫБОР все будет корректно работать, но запрос становится менее читабельным с кучей ветвей, а с ЕСТЬNULL все симпатичнее. мне интереснее почему запрос 1 и запрос 2 возвращает разные результаты. |
|||
3
dmpl
20.03.12
✎
13:43
|
(0) Это не ошибка. Надо пробовать
&Префикс + ЕСТЬNULL(Доки.Организация.Код,"не указано") КАК КодОрганизации |
|||
4
mikecool
20.03.12
✎
13:45
|
(0) а в выборке запись вообще присутствует?
|
|||
5
mikecool
20.03.12
✎
13:45
|
+4 ибо
выбрать ЕстьNull("Один" + Номер, "Два") Из Документ.РеализацияТоваровУслуг Где Номер = "23232323232321" не вернет ни одной записи |
|||
6
vvp117
20.03.12
✎
13:46
|
Запись присутствует.
См. вопрос с места: Но проще ее увидеть в пустой конфигурации (я использовал основной режим конфигурации [Обычное приложение]). Создаем пустую конфигурацию с объектами: 1. Справочник [Сотрудники]. 2. Справочник [Организации] (тип кода, что ВАЖНО, - Строка). 3. Независимый непериодический регистр сведений [Документы] с измерением [Сотрудник] (тип: СправочникСсылка.Сотрудники) и ресурсом [Организация] (тип: СправочникСсылка.Организации). Запускаем режим [Предприятие] и добавляем в регистр одну запись, в которой заполняем поле [Сотрудник], а поле [Организация] оставляем пустым. |
|||
7
Sammo
20.03.12
✎
13:48
|
План запросов какой?
|
|||
8
vvp117
20.03.12
✎
13:48
|
(3) префикс не нужно прибавлять к результату, иначе, если Доки.Организация.Код ЕСТЬ NULL, будем иметь на выходе такое: "СЗне указано".
|
|||
9
vvp117
20.03.12
✎
13:49
|
(7) как, используя консоль запросов, увидеть план запросов?
|
|||
10
Axel2009
20.03.12
✎
13:53
|
ВЫБРАТЬ СтатьяЗатрат.Код, ЕСТЬNULL(СтатьяЗатрат.Код, "0") КАК Поле1 ИЗ Справочник.Номенклатура ГДЕ Ссылка = &Ссылка
возвращает "", "0" 1С:Предприятие 8.2 (8.2.15.294) |
|||
11
dmpl
20.03.12
✎
14:05
|
(8) Ну так используй ВЫБОР.
Что же касается сути вопроса - это классическая ловушка с неявным приведением типов. |
|||
12
rs_trade
20.03.12
✎
14:08
|
ветку не читал, сходу &Префикс + NULL не есть правильно
|
|||
13
vvp117
20.03.12
✎
14:12
|
(10) интересно, что в 1С:Предприятие 8.1 (8.1.15.14) аналогичный код работает корректно
|
|||
14
vvp117
20.03.12
✎
14:13
|
(12) почему не правильно? на NULL что не умножай, будет NULL, что не прибавляй - NULL. Это весьма удобно.
(11) можно подробнее про неявное приведение типов? |
|||
15
Ненавижу 1С
гуру
20.03.12
✎
14:15
|
1С опять недопоняла NULL, а все придумывает Неопределено
Пусть с NULL научатся работать! |
|||
16
Wern
20.03.12
✎
14:19
|
Сложение тут не причем.С чего бы коду быть NULL ты же не из соединения берешь код, вот если бы у тебя было "ОРГ.Код" был бы NULL, а так явно "Неопределено".
|
|||
17
dmpl
20.03.12
✎
14:20
|
(13) Ну, значит, повезло.
(14) При неявной типизации первый аргумент операции сложения, как правило, определяет тип результата (т.е., если к строке число прибавить - в лучшем случае будет строка в виде конкатенации 2 строк - исходной и преобразованного в строку числа, в худшем - вообще ошибка). Разыменовывание неопределенной ссылки и приведение ее к типу Строка для сложения с строковым префиксом априори дает неопределенный результат. Не факт что NULL. |
|||
18
Ненавижу 1С
гуру
20.03.12
✎
14:24
|
(16) не суть важно откуда, это неявное соединение - иди учи матчасть
|
|||
19
vvp117
20.03.12
✎
14:25
|
(10) Вы правы.
Дело в версии платформы, установил 1С:Предприятие 8.2 (8.2.15.294) и проблема решилась. Кстати, аналогичный запрос в Microsoft SQL Server Management Studio (10.0.1600.22) также отрабатывает корректно. (17) Спасибо за разъяснение Ну в данном случае с 1С просто потребовалось обновиться. Всем спасибо. Вопрос закрыт. |
|||
20
Axel2009
20.03.12
✎
14:27
|
(17) если есть хоть один NULL, то абсолютно монопенисуально какой первый. все становится NULL
|
|||
21
dmpl
20.03.12
✎
14:30
|
(19) Чтобы потом опять вдруг не перестало работать - лучше избегать сложения разнотипных аргументов. Это относится ко всем языкам программирования, на таких ошибках многие шишки набивают.
(20) А кто сказал, что при неявном преобразовании к типу Строка будет NULL? А вдруг Неопределено? ;) |
|||
22
Ненавижу 1С
гуру
20.03.12
✎
14:31
|
(21) больше кидай на вентилятор
|
|||
23
Axel2009
20.03.12
✎
14:32
|
(21) стандарт SQL сказал
|
|||
24
dmpl
20.03.12
✎
14:35
|
(23) А запросы вы на языке SQL пишите, да? И давно он запросы на русском языке стандартизировал?
|
|||
25
Ненавижу 1С
гуру
20.03.12
✎
14:38
|
(24) гнилые отмазы 1с-филов-sql-фобов
|
|||
26
Axel2009
20.03.12
✎
14:39
|
(24) т.е. вы предполагаете, что 1с анализирует
&Префикс + колонкакакаято и преобразует в чтото наподобии: ВЫБОР КОГДА колонкакакаято ЕСТЬ NULL ТОГДА &Префикс ИНАЧЕ &Префикс + колонкакакаято КОНЕЦ так чтоли? |
|||
27
vvp117
20.03.12
✎
14:39
|
(23), (21) как бы намекает, что от 1С можно ожидать внезапного выхода за рамки стандартов SQL. Ведь в 8.1.15.14 этой ошибки нет, в 8.2.14.519 она вдруг появляется, а в 8.2.15.294 ее снова нет! блуждающий баг...
|
|||
28
Omskdizel
20.03.12
✎
14:42
|
(27) Закрыто только полвопроса. Решение показало то, что вторые полвопроса надо срочно решать, а именно: такие неоднозначные конструкции при правильном подходе приходить в голову не должны, как следствие будете в достаточно большой мере защищены от прихотей реализации 1С.
|
|||
29
Axel2009
20.03.12
✎
14:42
|
(27) нужен текст запроса SQL, в который преобразуется первоначальный запрос
|
|||
30
Omskdizel
20.03.12
✎
14:44
|
(29) Сдается мне это даже академическим интересом трудно считать. Смысла просто нет.
|
|||
31
dmpl
20.03.12
✎
14:44
|
(25) Да мне все равно, я такое сложение просто не буду использовать. Нигде.
(27) Кстати, а если попробовать явно использовать ВЫРАЗИТЬ()? |
|||
32
Axel2009
20.03.12
✎
14:49
|
(30) академический есть. вон разобрали что происходит если в список значение разные типы данных задавать.. теперь все в курсе что так лучше не делать
|
|||
33
vvp117
20.03.12
✎
14:50
|
(28) почему не должны? Например, в SQL такая конструкция находится в рамках разумного, ну а в 1С, конечно, стоит подстраховаться.
(31) пробовал ВЫРАЗИТЬ, не помогло. |
|||
34
vvp117
20.03.12
✎
14:51
|
(32) можно ссылку на тему? Интересно.
|
|||
35
Axel2009
20.03.12
✎
15:05
|
Форум | Правила | Описание | Объявления | Секции | Поиск | Книга знаний | Вики-миста |