Вход | Регистрация
 
1С:Предприятие :: 1С:Предприятие 8 общая

Поиск в ВИДе (внешнем источнике данных): не находится запись с id = 0

Поиск в ВИДе (внешнем источнике данных): не находится запись с id = 0
Я
   Cyberhawk
 
29.04.21 - 16:46
Во внешней БД MSSQL создать таблицу с двумя колонками:
1. "id", тип (int), первичный самовозрастающий ключ, у которого в настройках (identity specification) указать: identity seed = 0, identity increment = 1
2. "price", имя и тип не имеют значения, но для простоты пусть это будет число (int)

Подключаем эту таблицу к любой базе 1С, поддерживающей внешние источники данных (~8.3.5+): в метаданных указываем, что таблица - это объектные данные, поле ключа = id, только чтение для этого поля выставляем в истину.

Добавляем в таблицу пару записей:
id = 0, price = 100
id = 1, price = 200

Важно, чтобы в таблице образовалась запись с id = 0.

-------
Все написанное выше можно пропустить, а для эксперимента взять любую существующую у вас во внешней БД таблицу, в которой есть запись со значением в поле ключа = 0 (число ноль).

Далее (суть): выполняем в предприятии код https://paste1c.ru/1e868lb7ocjn

ИмяВИДа = "DWH";
ИмяТаблицыВИДа = "Table1";
ИмяПоляСДанными = "price";

//ОчиститьСообщения();


ТаблицаВИД = ВнешниеИсточникиДанных[ИмяВИДа].Таблицы[ИмяТаблицыВИДа];

ЗначениеДляПоиска1 = 100;
ЗаписьВИДСсылка1 = ТаблицаВИД.НайтиПоПолю(ИмяПоляСДанными, ЗначениеДляПоиска1);
Сообщить("Пустая ссылка: " + ЗаписьВИДСсылка1.Пустая());

ЗначениеДляПоиска2 = 200;
ЗаписьВИДСсылка2 = ТаблицаВИД.НайтиПоПолю(ИмяПоляСДанными, ЗначениеДляПоиска2);
Сообщить("Пустая ссылка: " + ЗаписьВИДСсылка2.Пустая());

ЗначениеДляПоиска3 = 777;
ЗаписьВИДСсылка3 = ТаблицаВИД.НайтиПоПолю(ИмяПоляСДанными, ЗначениеДляПоиска3);
Сообщить("Пустая ссылка: " + ЗаписьВИДСсылка3.Пустая());


Будут выданы следующие сообщения:

Пустая ссылка: Да
Пустая ссылка: Нет
Пустая ссылка: Да

А ожидалось, что будут сообщения:

Пустая ссылка: Нет
Пустая ссылка: Нет
Пустая ссылка: Да

Т.е. если в результате поиска найдена запись с id = 0, то она трактуется платформой как пустая ссылка.

Платформа: 8.3.15.1830
Режим совместимости: 8.3.9

Кто может проверить - проверьте, пожалуйста, у вас так же ведет себя платформа?
   Вафель
 
1 - 29.04.21 - 16:49
а там точно 0 а не null?
   Cyberhawk
 
2 - 29.04.21 - 17:03
   ДенисЧ
 
3 - 29.04.21 - 17:14
"Платформа: 8.3.15.1830
Режим совместимости: 8.3.9"

Это ты кого покемоном назвал??
   Cyberhawk
 
4 - 29.04.21 - 17:18
Удалось обойти такое поведение, в метаданных конфигурации указав в качестве поля ключа не колонку "id", а любую другую колонку, которая не содержит число ноль.
После этого приведенный выше код стал работать ожидаемо (запись стала находиться).
   TormozIT
 
5 - 29.04.21 - 18:55
Пустое значение типа колонки таблицы внешнего источника у 1С трактуется как пустая ссылка - так уже давно работает. Конечно в этом есть неудобства. Но пустая ссылка ссылочному типу (объектной таблице) необходима. Как еще ее можно реализовать кроме как пустым значением типа ключевого поля?
   Ненавижу 1С
 
6 - 29.04.21 - 22:08
(5) как у всех остальных людей вне 1с - через null
   TormozIT
 
7 - 29.04.21 - 22:39
(6) пустая ссылки и NULL - разные значения. А NULL - вообще особое значение. Его уж точно нельзя использовать для обозначения пустой ссылки, иначе левое соединение будет давать пустые ссылки вместо NULL.
   acht
 
8 - 29.04.21 - 23:37
(6) > как у всех остальных людей вне 1с
Это у тех, кто в своем стеке внезапно изобрел и одновременно использует null и System.DbNull м вдобавок не может расклеить в запросах NULL и пустую строку?

Ну-ну.
   BeerHelpsMeWin
 
9 - 29.04.21 - 23:39
Тоже пришел к тому, что в ВИДах стоит использовать свое 1с-ное поле ключа.
   BeerHelpsMeWin
 
10 - 29.04.21 - 23:40
Но у меня только одна сторона пишет, а вторая читает. Если обе будут писать-читать, будет непросто.
   Конструктор1С
 
11 - 30.04.21 - 05:07
(6) null создаёт массу неудобств
   Ненавижу 1С
 
12 - 30.04.21 - 06:36
(7) (8) (11) да я и не спорю
И ООП опасно и ФП вредно
   Ненавижу 1С
 
13 - 30.04.21 - 06:42
(8) передёргиваете
null и System.DbNull - это интерпретация зависит от того какие средства вы используете. В СУБД самой такого нет

не может расклеить в запросах NULL и пустую строку - Оракал признал это архитектурной ошибкой. В других СУБД все ок
   acht
 
14 - 30.04.21 - 07:49
(13) > передёргиваете 
То есть предлагать выражать чисто 1Совсвое понятие "пустая ссылка" через NULL это одно, а
"интерпретация зависит от того какие средства вы используете" - это другое. Ну ок, что.
   Ненавижу 1С
 
15 - 30.04.21 - 08:29
(14) и опять передёргиваете

В 1с есть и null и неопределено и пустые ссылки одновременно. В .net на уровне linq2sql не требуется работать с DbNull. На уровне ado.net другой разговор.
   Cyberhawk
 
16 - 30.04.21 - 09:31
(5) Могли бы возвращать Неопределено в методе НайтиПоПолю, если запись в таблице не найдена.
Выходит, что контракт описан не полностью: https://i.imgur.com/BJEGSRA.png
И пустая ссылка будет возвращаться если найдена запись, в поле ключа которой содержится пустое значение того типа, что задан для этого ключа в метаданных конфигурации.
   Ненавижу 1С
 
17 - 30.04.21 - 09:43
(16) поэтому явные запросы предпочтительнее
   Cyberhawk
 
18 - 30.04.21 - 09:45
(9) Ну столь радикально во всех случаях поступать все же, наверное, не стоит. Все-таки самовозрастающий первичный числовой ключ в MSSQL по умолчанию нумеруется с 1 (при создании новой таблицы).
Просто мне попалась таблица, где этот ключ начинается с нуля. И объектная модель поиска подложила вот такой сюрприз.
   Cyberhawk
 
19 - 30.04.21 - 10:06
(17) Да, это кажется гораздо более универсальной альтернативой (4), благодарю.
Проверил: при отсутствии записи в ВИДе результат запроса пустой, иначе - непустой в любом случае (в результате запроса присутствует в т.ч. и "плохая" запись с id = 0).

Вывод: если в объектной таблице ВИДа потенциально может присутствовать запись со значением ключа, соответствующим пустому значению того типа, что указан в метаданных 1С для этого поля ключа, то не следует пользоваться объектной моделью (НайтиПоПолю), а следует пользоваться запросом.
   Ненавижу 1С
 
20 - 30.04.21 - 10:21
(19) + нужен аналог LINQ в 1С
   Cyberhawk
 
21 - 17.05.21 - 08:56
Дополнение к (19) для истории: явный запрос отлично решает только задачу _поиска (проверки существования)_ существующей в ВИДе "плохой" (с id = 0) записи, но он не решает задачу манипулирования (получения, редактирования и обновления) такой записи.

Если интерактивно (в дин. списке) спозиционироваться на такой записи и перейти к ее редактированию (двойной клик или F2), то открывается форма создания новой записи (и, соответственно, в БД добавляется новая запись, а не обновляется интересующая нас "плохая").
Программно (через объектную технику работы с таблицей ВИДа, тип которой "Объектные данные") также невозможно получить объект такой записи (чтобы в нем какое-нибудь другое поле-реквизит поменять и обновить такую "плохую" запись в БД).

Поэтому рецепт из (19) - если нужна возможность не только проверять факт существования "плохой" записи, но и обновлять ее - нужно обязательно применять совместно с (4): в этом случае получится как интерактивно, так и программно получать и обновлять такую "плохую" запись. Также корректно будет работать и возможность ссылаться на эту запись в реквизитах других объектах конфигурации. Ну и, собственно, раз "НайтиПоПолю" тоже будет работать в этом корректно, то отпадает необходимость и переписывать код по рецепту из (19).
   mistеr
 
22 - 17.05.21 - 09:14
(19) В этом случае не надо объявлять такую таблицу объектной. Объектная таблица по определению не должна содержать пустых ссылок, там ссылка это ПК.

Возможным архитектурным решением проблемы (0) была бы возможность в метаданных ВИД указывать, какое значение ключа примитивного типа будет использоваться в качестве "пустой ссылки".
   Cyberhawk
 
23 - 17.05.21 - 09:25
(22) Сменить тип таблицы с объектной на необъектную тоже является рецептом лечения обозначенной в теме проблемы.
Только в этом случае нужно помнить, что придется переписать весь код по работе с этой таблицей ВИДа (который добавляет в нее или обновляет в ней записи).


Список тем форума
 
Компьютеры — прекрасное средство для решения проблем, которых до их появления не было.
ВНИМАНИЕ! Если вы потеряли окно ввода сообщения, нажмите Ctrl-F5 или Ctrl-R или кнопку "Обновить" в браузере.