PDA

Просмотр полной версии : Ошибка чтение несуществующего элемента



AlexBut
04.03.2025, 16:42
Создал массив структуры типа параметр_1 .id (datetime, receivedatetime,value и т.д.)(структура описана в библиотеке типа структура_1 поля id,datetime,receivedatetime,value..).
И всё работает как надо- кроме того, что выдаются системные сообщения(после запуска проекта)
-"попытка чтения несуществующего элемента". И действительно 1-ю минуту(так настроено) масив пустой
и вполне оправданы такие сообщения , но даже после чтения таблиц БД, когда массив заполняется(через основной параметр
PostgresSQL -запроса, который имеет тот же тип(тот же массив той же структуры)).
(SQl-запрос типа select * from имя-таблицы where id=1 order by datetime DESC) СКАДА продолжает высчитывать ошибки обращения
к несуществующему элементу, в программах ST типа(или цикла WHILE):
IF параметр_1[1].datetime<>NULL
THEN
last_value:=параметр_1[1].value; //и это работает!!!
END_IF;
хотя точно параметр_1[1].datetime существует и не равен NULL(и value существует),
но системные сообщения ругаются что попытка чтения несуществующего элемента
и наращивают счётчик ошибок.
Если бы не эти системные сообщения , то можно было бы сказать , что всё работает.
Никто не встречался с такой проблемой в MS4D?

Dorr
05.03.2025, 08:18
вроде как NULL не понимает, поэтому и ошибку выдает!

imaex
05.03.2025, 08:44
IF параметр_1[1].datetime<>NULL


Это в каком языке такие конструкции? В SQL для NULL обычно применятся что-то вроде "is not NULL", операции сравнения с NULL не работают.

melky
05.03.2025, 08:57
Ну очевидно же, что ST. Тоже не знаю, как там на null проверять.
Если это строка например.

imaex
05.03.2025, 11:12
Ну очевидно же, что ST. Тоже не знаю, как там на null проверять.
Если это строка например.

Проще в резалтсете заменять null на нечто заведомо не существующее, но не null.
nvl(datetime, to_date('01.01.0001')) - как-то так, детали от диалекта зависят.

AlexBut
05.03.2025, 11:18
А как в MS4D проверять параметр на NULL?

melky
05.03.2025, 11:28
как вариант проверять на 0 или на длину строки, не равную 0

AlexBut
05.03.2025, 11:39
На такую конструкцию компилятор не ругается :
i_incr2:=1;
WHILE Параметр_2[i_incr2].datetime<>Null
DO
i_incr2:=i_incr2+1;
last_row_ev:=i_incr2-1;
END_WHILE;
Но MS4D в процессе исполнения выдаёт в системном окне сообщений "обращение к несуществующему элементу" и счётчик этого сообщения постоянно растёт.
А как проверить что строка не Null(читаю таблицу БД и заранее неизвестно сколько строк заполнено).
Тип Параметра_2 Array Of Структура_2 (При компиляции нет ошибок).
И результат работы этой программы правильный и если бы не ошибка исполнения...

imaex
05.03.2025, 12:28
Вы в самом запросе null подменяйте на нечто осмысленное, выше я примерно подсказал - как. Т.е.

select nvl(datetime_col, to_date('01.01.0001')) as datetime_col from my_table where <условие>

Как оно (nvl) в PostgresSQL будет выглядеть - я не знаю, не знаком с ним. Но наверняка то же самое либо аналог есть.

или в самом запросе дополнить условие where типа ...and datetime_col is not null

чтобы заведомо строки с null'ами не получать. Как вариант.

capzap
05.03.2025, 12:40
из дискуссии я так и не понял проблема в базе или в МС
если по базе то не думая, есть такие варианты 82312

AlexBut
05.03.2025, 12:48
из дискуссии я так и не понял проблема в базе или в МС
если по базе то не думая, есть такие варианты 82312

Проблема не в базе и тот фрагмент кода который я привёл работает с массивом , который успешно
заполняется из SQL-запроса. Но сколько там строк(УСПД сбрасывает в БД измеренные значения)
заранее неизвестно- есть желание отобразить последние 100 но их может быть и меньше

imaex
05.03.2025, 12:49
из дискуссии я так и не понял проблема в базе или в МС

Дык, никто из присутствующих не в курсе, как в MS4D переменные с неопределённым значением обрабатывать. :confused:

imaex
05.03.2025, 13:10
Проблема не в базе и тот фрагмент кода который я привёл работает с массивом , который успешно
заполняется из SQL-запроса. Но сколько там строк(УСПД сбрасывает в БД измеренные значения)
заранее неизвестно- есть желание отобразить последние 100 но их может быть и меньше

Оно априори никогда неизвестно - кол-во строк в результирующем наборе. Если нужно ограничить кол-во строк в результирующем наборе - используйте в запросе TOP, ROWNUM или что там в Postgre.

Дарю: яндекс (https://yandex.ru/search/?text=select+top+100+sql+%D1%81%D0%B8%D0%BD%D1%82% D0%B0%D0%BA%D1%81%D0%B8%D1%81+postgresql&lr=24&clid=2270455&win=587&src=suggest_B)

Там в примерах заодно подспудно поясняется, что есть "первые" и "последние" в SQL.

Что касается приведённого Вами куска кода, конструкция типа что_то<>NULL сразу вызывает вопросы у любого, работавшего с RDBMS. Как оно в MS4D - я лично не знаю, может и правильно.

capzap
05.03.2025, 13:13
Дык, никто из присутствующих не в курсе, как в MS4D переменные с неопределённым значением обрабатывать. :confused:

82315
документация же есть

imaex
05.03.2025, 13:16
документация же есть

У кого есть, а кому и без надобности.

AlexBut
06.03.2025, 06:01
82315
документация же есть

Может не по глазам но я не нашёл.
И да-проблема не в базе, база успешно считывается и результат успешно закидывается в массив СКАДА,
но при попытке определить а сколько строк заполнено возникает эта проблема.

asuwcc
06.03.2025, 08:16
День добрый.

В программе ST сначала локальную переменную типа массив создать и инициализировать через CREATE_ARRAY (https://support.mps-soft.ru/Help-web/index.html?create_array.html). Потом присвоить на выход.
Или существующий массив в ST сделать как InOut и перед заполнением применять RESIZE_ARRAY.
В качестве init_value использовать локальную переменную, которая определена типом, как элемент массива.

capzap
06.03.2025, 10:36
Может не по глазам но я не нашёл.
И да-проблема не в базе, база успешно считывается и результат успешно закидывается в массив СКАДА,
но при попытке определить а сколько строк заполнено возникает эта проблема.
с помощью ИИ можно получить ответ как это сделать, например
SELECT
*,
COUNT(*) OVER () as total_orders
FROM orders as t
WHERE t.lasttime >= (NOW() - INTERVAL '10 s')
ORDER BY t.lasttime DESC
LIMIT 100;
Оконная функция COUNT(*) OVER () не учитывает LIMIT в подсчёте, поэтому вы получите общее количество строк до применения LIMIT
COUNT(*) обычно работает быстрее чем COUNT(столбец), так как не требует проверки на NULL

82324

AlexBut
06.03.2025, 11:00
Нашёл length:=UPPER_BOUND(array,1)