NULL, да не NULL

27.08.15

Разработка - Математика и алгоритмы

Если вы пользуетесь в запросе конструкциями вида

... ГДЕ Продукция.Родитель = &А ИЛИ Продукция.Родитель.Родитель = &А ИЛИ ...

Если вы пользуетесь в запросе конструкциями вида

... ГДЕ Продукция.Родитель = &А ИЛИ Продукция.Родитель.Родитель = &А ИЛИ ...

для определения принадлежности элемента справочника определенным папкам, то надо иметь в виду некоторые особенности.
В коде вы можете спокойно брать родителя любого уровня и будете получать просто пустую ссылку, если вышестоящего родителя нет.

Например

Справочники.Номенклатура.ПустаяСсылка().Родитель

- это пустая ссылка.
В запросе всё немного не так.

Родитель корневого элемента будет пустая ссылка, а все вышестоящие родители будут равны NULL.

Такой запросец (имитирует обращение к предку второго уровня коренвого элемента, т.к. предок первого уровня это пустая ссылка)

ВЫБРАТЬ
    (ЗНАЧЕНИЕ(Справочник.Номенклатура.ПустаяСсылка)).Родитель

вернет NULL.

Что интересно, SQL запрос

ВЫБРАТЬ
    (ЗНАЧЕНИЕ(Справочник.Номенклатура.ПустаяСсылка)).Родитель.Родитель

тоже вернет NULL.

Хотя, казалось бы, он эквивалентен запросу

ВЫБРАТЬ
    (NULL).Родитель

который приводит к ошибке.

Дальше еще интереснее.
Вот такой незамысловатый запрос

 

ВЫБРАТЬ
    ВЫБОР
        КОГДА НЕ ЗНАЧЕНИЕ(Справочник.Номенклатура.ПустаяСсылка) В (
                NULL
              )
        ТОГДА 1
        ИНАЧЕ 2
    КОНЕЦ


вернет 1, ну действительно, вроде логично. Хотя операции сравнения с NULL вегда возвращают ЛОЖЬ и необходимо использовать конструкцию ЕСТЬ NULL.

Но с какого-то перепугу

 

ВЫБРАТЬ
    ВЫБОР
        КОГДА НЕ ЗНАЧЕНИЕ(Справочник.Номенклатура.ПустаяСсылка) В (
                (ЗНАЧЕНИЕ(Справочник.Номенклатура.ПустаяСсылка)).Родитель
              )
        ТОГДА 1
        ИНАЧЕ 2
    КОНЕЦ


возвращает 2.

Кстати, если в двух последних запросах В заменить на В ИЕРАРХИИ, то первый запрос так и будет возвращать 1, а второй запрос начнет сыпать ошибку.

Подводя итог: обращение к родителям вышестоящего уровня в запросе может привести к псевдо-NULL значениям, которые ведут себя не совсем как NULL. Хотя для них операция ЕСТЬ NULL будет истина. Чтоб оградить себя от подобных казусов, все обращения к "дедам", "прадедам" и т.д. элементов справочников следует заключать в конструкцию ISNULL.

P.S. Не благодарите за ваше острое желание проверить тексты запросов, содержащих Родитель.Родитель

программирование

См. также

Метод Дугласа-Пойкера для эффективного хранения метрик

Математика и алгоритмы Платформа 1C v8.2 Конфигурации 1cv8 Россия Абонемент ($m)

На написание данной работы меня вдохновила работа @glassman «Переход на ClickHouse для анализа метрик». Автор анализирует большой объем данных, много миллионов строк, и убедительно доказывает, что ClickHouse справляется лучше PostgreSQL. Я же покажу как можно сократить объем данных в 49.9 раз при этом: 1. Сохранить значения локальных экстремумов 2. Отклонения от реальных значений имеют наперед заданную допустимую погрешность.

1 стартмани

30.01.2024    1756    stopa85    12    

33

Алгоритм симплекс-метода для решения задачи раскроя

Математика и алгоритмы Бесплатно (free)

Разработка алгоритма, построенного на модели симплекс-метода, для нахождения оптимального раскроя.

19.10.2023    4426    user1959478    50    

34

Регулярные выражения на 1С

Математика и алгоритмы Инструментарий разработчика Платформа 1С v8.3 Мобильная платформа Россия Абонемент ($m)

Что ж... лучше поздно, чем никогда. Подсистема 1С для работы с регулярными выражениями: разбор выражения, проверка на соответствие шаблону, поиск вхождений в тексте.

1 стартмани

09.06.2023    7465    4    SpaceOfMyHead    17    

56

Модель распределения суммы по базе

Математика и алгоритмы Платформа 1С v8.3 Россия Абонемент ($m)

Обычно под распределением понимают определение сумм пропорционально коэффициентам. Предлагаю включить сюда также распределение по порядку (FIFO, LIFO) и повысить уровень размерности до 2-х. 1-ое означает, что распределение может быть не только пропорциональным, но и по порядку, а 2-ое - это вариант реализации матричного распределения: по строкам и столбцам. Возможно вас заинтересует также необычное решение этой задачи через создание DSL на базе реализации текучего интерфейса

1 стартмани

21.03.2022    7856    7    kalyaka    11    

44

Изменения формата файлов конфигурации (CF) в 8.3.16

Математика и алгоритмы Платформа 1С v8.3 Бесплатно (free)

Дополнение по формату файлов конфигурации (*.cf) в версии 8.3.16.

16.12.2021    4446    fishca    13    

36

Интересная задача на Yandex cup 2021

Математика и алгоритмы Бесплатно (free)

Мое решение задачи на Yandex cup 2021 (frontend). Лабиринт. JavaScript.

12.10.2021    8843    John_d    73    

46

Механизм анализа данных. Кластеризация.

Математика и алгоритмы Анализ учета Платформа 1С v8.3 Анализ и прогнозирование Бесплатно (free)

Подробный разбор, с примером использования, встроенного механизма кластеризации 1С.

31.08.2021    7808    dusha0020    8    

70
Комментарии
В избранное Подписаться на ответы Сортировка: Древо развёрнутое
Свернуть все
1. dmpas 418 27.08.15 13:09 Сейчас в теме
операции сравнения с NULL вегда возвращают ЛОЖЬ

Это ересь, за которую надо сжигать на кострах.

цитата с ИТС:
Любая операция сравнения двух значений, в которой участвует хотя бы одно значение NULL, дает результат, аналогичный значению Ложь.

АНАЛОГИЧНЫЙ значению Ложь, но не Ложь.
jobkostya1c_ERP; Восьмой; Evil Beaver; JohnyDeath; emakei; kuzyara; GusevNA; denis_aka_wolf; Yashazz; kuntashov; Magnastrag; awk; vano-ekt; +13 Ответить
2. vandalsvq 1538 27.08.15 14:29 Сейчас в теме
(0), Справочник.Родитель.Родитель в запросе, если Справочник.Родитель = NULL не есть тоже самое что NULL.Родитель, хотя бы потому что происходит следующее:
текст запроса вроде

ВЫБРАТЬ Т.Родитель.Родитель КАК Родитель
ИЗ Справочник.Контрагенты КАК Т


Преобразуется в запрос вида

ВЫБРАТЬ Т2.Родитель КАК Родитель
ИЗ Справочник.Контрагенты КАК Т
ЛЕВОЕ СОЕДИНЕНИЕ Справочник.Контаргенты КАК Т2
ПО Т.Родитель = Т2.Ссылка


все это называется "неявное соединение"
3. leksmut 350 27.08.15 15:46 Сейчас в теме
(2) vandalsvq, понятно,но что мешало при левом соединении использовать isnull, было бы логично видеть пустую ссылку
4. Famza 84 28.08.15 08:33 Сейчас в теме
ВЫБРАТЬ
(ЗНАЧЕНИЕ(Справочник.Номенклатура.ПустаяСсылка)).Родитель
вернет NULL.


Хотя, казалось бы, он эквивалентен запросу

ВЫБРАТЬ
(NULL).Родитель

Если следовать вашей логике, получается, что ЗНАЧЕНИЕ(Справочник.Номенклатура.ПустаяСсылка) это NULL?
Или я что-то упустил в языке программирования 1С? Можете указать часть-номер_страницы из ЖКК или ссылку на ресурсе http://its.1c.ru/?
5. klinval 337 28.08.15 09:20 Сейчас в теме
(4) Famza, Прикольное у вас цитирование:
Вместо:
ВЫБРАТЬ
(ЗНАЧЕНИЕ(Справочник.Номенклатура.ПустаяСсылка)).Родитель
вернет NULL.

Что интересно, SQL запрос

ВЫБРАТЬ
(ЗНАЧЕНИЕ(Справочник.Номенклатура.ПустаяСсылка)).Родитель.Родитель
тоже вернет NULL.

Хотя, казалось бы, он эквивалентен запросу

ВЫБРАТЬ
(NULL).Родитель
Показать

Вы цитируете:
ВЫБРАТЬ
(ЗНАЧЕНИЕ(Справочник.Номенклатура.ПустаяСсылка)).Родитель
вернет NULL.

Хотя, казалось бы, он эквивалентен запросу

ВЫБРАТЬ
(NULL).Родитель

И получается, что автор имел ввиду не то что ЗНАЧЕНИЕ(Справочник.Номенклатура.ПустаяСсылка) это NULL а то что ЗНАЧЕНИЕ(Справочник.Номенклатура.ПустаяСсылка)).Родитель это NULL...

А что касается самой публикации: мне вроде ни разу не приходилось пользоваться конструкцией Родитель.Родитель.Родитель.... т.к. я обычно пользуюсь конструкцией:
ГДЕ Родитель В ИЕРАРХИИ(&Родитель)
7. leksmut 350 31.08.15 12:38 Сейчас в теме
(5) klinval, (6) vano-ekt,
А если нужно выбрать элементы внутри папки, лежащие ровно на заданной глубине иерархии?


9. vandalsvq 1538 31.08.15 15:12 Сейчас в теме
(7) значит у вас неверно выстроена архитектура приложения. Запросы не должны зависеть от данных которые они собирают. Это чуть ли не аксиома.
В идеале запрос надо писать так чтобы не было ни одной идеи смотреть данные.
10. Xershi 1475 31.08.15 15:17 Сейчас в теме
(9) vandalsvq, а если заказчик хочет видеть иерархию и ТЗ дает такое. Что вы будете делать?
11. vandalsvq 1538 31.08.15 15:54 Сейчас в теме
(10) Xershi, группировка по иерархии не помогает? Настройками вывести на форму чтобы сохранили какие уровни нужны тоже? Или задачу более подробно опишите.
А вообще хорошая архитектура - это сложно, так же сложно как удобная форма, особенно когда речь идет про 1С )))))
6. vano-ekt 123 31.08.15 11:00 Сейчас в теме
Если вы пользуетесь в запросе конструкциями вида
... ГДЕ Продукция.Родитель = &А ИЛИ Продукция.Родитель.Родитель = &А ИЛИ ...

то оторвать бы вам руки :-D
8. Evil Beaver 8108 31.08.15 13:44 Сейчас в теме
Не нравится мне эта статья, и даже лень формулировать почему именно
DrAku1a; dmpas; JohnyDeath; emakei; denis_aka_wolf; kuntashov; zqzq; Xershi; +8 Ответить
16. leksmut 350 02.09.15 09:45 Сейчас в теме
(8) Evil Beaver,
полезные вещи вообще редко нравятся (рыбий жир, манная каша, закаливание, гимнстика по утрам)
12. Lapitskiy 1057 31.08.15 18:24 Сейчас в теме
"Ученые скрестили слона и слона. Не для научных целей, а просто так, позырить"
13. a_titeev 31 01.09.15 00:56 Сейчас в теме
что еще за "псевдо-NULL"? жесть... Эдгар Кодд должен был перевернуться в гробу со своим третьим правилом реляционных СУБД...
Да, и еще. Напомню, если кто не знает, одно из правил операций с NULL:
Любая операция сравнения с NULL (даже операция «NULL = NULL»), даёт в результате значение «неизвестность» (UNKNOWN). Окончательный результат при этом зависит от полного логического выражения в соответствии с таблицей истинности логических операций. Если сравнение с NULL есть вся логическая операция целиком (а не её часть), то результат её аналогичен FALSE (выражение вида IF <что-то> = NULL THEN <действие1> ELSE <действие2> END IF всегда будет приводить к выполнению действия 2).


Кстати. Полез на всякий случай на Методическую поддержку - http://its.1c.ru/db/metod8dev#content:2590:hdoc. Есть забавная фраза - "Рекомендуется всегда пользоваться разыменованием полей там, где это возможно, чтобы не усложнять запросы лишними конструкциями." Вот отожгли они :) Надо было назвать тот раздел - "Как сделать вялоработающую/неработающую конфигурацию". Ибо именно такие рекомендации и приводят потом к конструкциям "...Родитель.Родитель.Родитель" в запросах. Хотя бывает и хуже. Например, ".Регистратор.Дата" :)
Labotamy; almierm; +2 Ответить
14. dolter 119 01.09.15 12:59 Сейчас в теме
(13) Самое интересное, что "Период" в движении не всегда равен "Регистратор.Дата"... Поэтому это еще не самое страшное )
17. cleaner_it 220 02.09.15 11:09 Сейчас в теме
(14) dolter, Регистратор.Дата = Период - это один из частных случаев
15. Rie 02.09.15 08:35 Сейчас в теме
"...Хотя, казалось бы, он эквивалентен запросу
ВЫБРАТЬ
(NULL).Родитель"
Да нет, не эквивалентен. "Точки" в запросах - это ведь, по сути, соединения, а не "вычислим, а потом ещё раз вычислим".
Оставьте свое сообщение