powered by simpleCommunicator - 2.0.60     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / FoxPro, Visual FoxPro [игнор отключен] [закрыт для гостей] / Глюк в конструкции SELECT ... INTO ARRAY
14 сообщений из 14, страница 1 из 1
Глюк в конструкции SELECT ... INTO ARRAY
    #32502975
qu-qu
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Наступил я тут на одни очень неприятные "грабли":

Написан был модуль, в котором очень широко и часто используются передачи наборов значений ("столбцов") из курсора в массив и обратно, причем массивы сами используются как средства для переноса наборов значений между различными функциями модуля...

Что-то типа такого:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
&&...
LOCAL arr2Price
DIMENSION arr2Price[ 1 ]
arr2Price[ 1 ] = .F.
=GetProps([price],@arr2Price,[prices])
FOR i =  1  TO ALEN(arr2Price)
?arr2Price[i]
NEXT
&&...

PROCEDURE GetProps
LPARAMETER cPropertyName, aPropsArray, cCursorName			

	DIMENSION aPropsArray[ 1 ]
	aPropsArray[ 1 ] = .F.
	SELECT EVAL(cPropertyName) FROM (cCursorName) INTO ARRAY aPropsArray

ENDPROC



При работе самого модуля, а также приложения, которое его использует - подобные переносы "столбцов" в локальные массивы и обратно происходят сотнями и тысячами вызовов, практически всегда без всяких сбоев...

Но, именно - "практически", т.к. вчера я наконец-то наткнулся на случай, когда это не так... :-((.
Не буду описывать сколько времени пришлось просидеть в дебаггере, чтобы наконец-то найти то сочетание курсора и массива, которые не соответствуют "друг-другу", но факт остается фактом - вижу собственными глазами: в курсоре одни значения, а в массиве (после выполнения SELECT ... INTO ARRAY) "немного" другие... :-((.
Почему "немного"?
Да потому что совпадают только первые строчки курсора и первые элементы массива, а последний элемент массива - ну никак не хочет совпадать со значением поля курсора... (бред какой-то, то 0 вместо "нормального" значения, то "старое" значение от какого-то давнего "хвоста", даже не похожее ни на текущее, ни на предыдущее).

Но самый тяжкий бред заключается в том, что, как я уже упоминал, курсоров для такой перекидки массивами используется до десятка, столбцов переносится около сотни, и вызывается все это не 1 десяток раз по ходу выполнения модуля, а такое странное поведение наблюдается строго в ДВУХ ОПРЕДЕЛЕННЫХ курсорах, и в каждом из них на ОДНОМ ОПЕРЕДЕЛЕННОМ столбце (названия столбцов не совпадают).

Не могу даже предположить - что это такое за глюк/баг/фича и откуда оно берется?
Пишу сюда только в надежде на то, что кто-нить может быть сталкивался с подобным "эффектом", или хотя бы слышал "краем уха".

З.Ы. все курсоры создаются с именами типа SYS(2015) путем получения данных с SQL-сервера через SQLEXEC(), все поля в курсорах имеют идентичные наименования и типы данных, курсоры пробовал создавать как в общей DataSession так и в приватной - "эффект" стойко сохраняется...
Если нужны еще какие-нить доп. сведения о "программном окружении" - спрашивайте...
...
Рейтинг: 0 / 0
Глюк в конструкции SELECT ... INTO ARRAY
    #32503040
Crip
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
А если заменить
SELECT EVAL(cPropertyName) FROM (cCursorName) INTO ARRAY aPropsArray
на
SELECT &cPropertyName FROM (cCursorName) INTO ARRAY aPropsArray

Как-то оно надежнее да и быстрее выглядит...
...
Рейтинг: 0 / 0
Глюк в конструкции SELECT ... INTO ARRAY
    #32503084
Непонятно, почему в вызываемой процедуре используется LPARAMETER.

Multiple items in ParameterList are separated by commas. LPARAMETERS creates local variables or arrays within a called program, procedure, or user-defined function. Use PARAMETERS to create private variables or arrays.

Может, здесь ошибка?
И потом, Вы уверены, что число считываемых в массив строк не превышает его максимально допустимого размера (65 000)?
...
Рейтинг: 0 / 0
Глюк в конструкции SELECT ... INTO ARRAY
    #32503157
sobutilnik
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
У меня было похожее, прилеплялся хвост от предыдущих вычислений, после чего COPY TO ARRAY выдавала неправильный массив. Чтобы избавиться от этого, делаю сначала RELEASE имя_массива.
...
Рейтинг: 0 / 0
Глюк в конструкции SELECT ... INTO ARRAY
    #32503190
qu-qu
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
по поводу SELECT &cPropertyName ...

Изначально в рабочем коде так и было, код до этого работал "правильно" около года на других задачах, но когда недавно возникла необходимость добавить ему еще "сфер применения" и стал проявляться описанный выше "эффект" - пришлось пробовать по ходу дела всевозможные "ухищрения", в том числе и замену макроподстановки на EVAL() - ничего не помогает... в одном и том же месте, один и тот же глюк...
(поэтому в примере я и оставил EVAL())

по поводу "Непонятно, почему в вызываемой процедуре используется LPARAMETER"

В том же разделе справки VFP про LPARAMETERS написано:
By default, DO ... WITH passes variables and arrays to procedures by reference . When a value is changed in the called procedure, the new value is passed back to the associated variable or array in the calling program ...

На мой взгляд, ничего "внятного" ни ваша цитата, ни моя - не содержат...
Ну и что - создаются локальные переменные (параметры) внутри процедуры, которая что-то копирует в массив, массив-то ей (процедуре) передается извне по ссылке , какая разница - будет ссылка локальной, или приватной? Сам-то массив так или иначе - все равно находится "вовне"...

Хотя, проверил я вариант и с PARAMETERS вместо LPARAMETERS - все... то... же... са-мо-е... :-(((
...
Рейтинг: 0 / 0
Глюк в конструкции SELECT ... INTO ARRAY
    #32503212
qu-qu
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
насчет "делаю сначала RELEASE имя_массива"

Можно немного поподробнее?
Релизить массив до передачи его по ссылке в процедуру, где он заполняется?
Или же - внутри процедуры релизить ссылку на массив, переданную в параметре? Тогда немного непонятно - что и как вернется из процедуры?

З.Ы. забыл еще насчет "предела в 65 000 элементов" - во всех рабочих примерах, на которых я наблюдаю данный гемор, всего-то навсего по 3 строчки/элемента... (т.е. первые 2 совпадают, третий - нет)
кста, по той же причине (наверное) не могут "прицепляться левые хвосты" от других массивов, т.к. все курсоры имеют по 3 строчки, и все массивы - по 3 элемента...
(в рабочем проекте - число строчек доходит до 15-20, но уж никак не превышает 100, не говоря уже про 65 000)
...
Рейтинг: 0 / 0
Глюк в конструкции SELECT ... INTO ARRAY
    #32503239
sobutilnik
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Конечно, до передачи, а то что же возвращать?
...
Рейтинг: 0 / 0
Глюк в конструкции SELECT ... INTO ARRAY
    #32503257
Crip
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Я кстати в VFP8 стараюсь в таких случаях использовать Collection вместо Array для передачи в процедуру. С объектам как-то проще ИМХО, да и глюков наверное меньше...
...
Рейтинг: 0 / 0
Глюк в конструкции SELECT ... INTO ARRAY
    #32503285
qu-qu
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
"Конечно, до передачи, а то что же возвращать?"

Да вот и я так же подумал, что "до передачи"... :-((
Беда только в том, что в рабочем коде до передачи ничего с массивами не делается, они только объявляются и инициализируются "фиктивными" значениями (.F.), ну точь-в-точь как в приведенном выше примере.

Надеюсь, не после инициализации же их релизить? А то и передавать-то по ссылке будет нечего... :-((

З.Ы. вот еще одна "хитрая особенность" пришла на ум, в рабочем коде как и в примере - прямо перед командой SELECT ... INTO ARRAY массивчик "урезается" до 1-го элемента и заполняется тем же "фиктивным" (.F.) значением... Через дебаггер видно, что это все замечательно выполняется, откуда появляется "левое" значение в 3-ем элементе после команды SELECT ... INTO ARRAY , если до нее - 3-его элемента (вроде бы) вообще не существовало?

З.Ы.Ы. насчет VFP8 и Collection это здорово ,но у меня к сожалению VFP6...
...
Рейтинг: 0 / 0
Глюк в конструкции SELECT ... INTO ARRAY
    #32503524
Фотография ВладимирМ
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Для определения локального массива обычно используется синтаксис:

Код: plaintext
LOCAL arr2Price( 1 )


А то, что у тебя - это лишнее. Т.е. все эти переопределения DIMENSION и aPropsArray[1] = .F. просто не нужны. Хотя, на результат вроде бы не влияет.

Вообще-то SYS(2015) не всегда дает уникальное имя. Нужна дополнительная проверка на факт использования такого имени другим куросром, что-то вроде:

Код: plaintext
1.
2.
3.
4.
LOCAL lcCursorName
lcCursorName = SYS( 2015 )
DO WHILE USED(m.lcCursorName)
	lcCursorName = SYS( 2015 )
ENDDO
...
Рейтинг: 0 / 0
Глюк в конструкции SELECT ... INTO ARRAY
    #32504201
qu-qu
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Спасибо, Владимир, что обратил внимание на мою проблему...
(очень хотел узнать именно твое мнение)

Но, видать, и тебе про такое "чудо" слыхивать до сих пор еще не доводилось.

Насчет "все эти переопределения DIMENSION и aPropsArray[1] = .F. просто не нужны" - в логике примера, пожалуй, что да...
Но в логике приложения приходится закладываться на то, что массив может поступить в процедуру заполнения уже "полным", а в курсоре, из которого должны выбраться новые значения, может не оказаться записей ваще... тогда опаньки - "старый" массив останется в нетронутом виде. Поэтому я и использую "урезание" массива до 1-го элемента и заполнение его "мусором", чтобы после SELECT ... INTO ARRAY проверить - а есть ли вообще в массиве "осмысленные" значения?
Полностью с тобой согласен насчет того, что все эти "танцы с бубном" на результат выгрузки из курсора в массив влиять не должны, и причиной ошибки тоже быть не могут... (хотя, на 100% как можно быть уверенным?)

По поводу уникальности SYS(2015) можно было бы и проверить, но опять же - в реальном приложении (не в примере) имена реальных курсоров кроме SYS(2015) имеют еще и "суффикс", который зависит от конкретного SQL-вызова, и фактически являются уникальными на 100% (проверено мной), т.е. эта "гипотеза" тоже не прокатывает...

З.Ы. попробую счаз изменить стиль объявления массивов с DIMENSION на LOCAL arrBlaBla[1] (типа - "хватаюсь за все соломинки"), если результата не будет - то и писать больше пока ничего не буду...
...
Рейтинг: 0 / 0
Глюк в конструкции SELECT ... INTO ARRAY
    #32504305
Фотография ВладимирМ
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Попробуй еще проверять факт наполнения массива по значению системной переменной _TALLY

Код: plaintext
1.
2.
3.
4.
5.
SELECT ... INTO ARRAY ...
IF _TALLY= 0 
* В выборку не попало ни одной записи, надо обнулить массив
DIMENSION aPropsArray[ 1 ]
aPropsArray = .F.
ENDIF


PS: Если не указывать размерность в команде присвоения - это означает присвоить значение ВСЕМ элементам массива
...
Рейтинг: 0 / 0
Глюк в конструкции SELECT ... INTO ARRAY
    #32504458
qu-qu
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
про _TALLY

Угу, в итоге так было и сделано... Сразу после SELECT ... INTO ARRAY идет проверка IF _TALLY > 0, а потом уже "все остальное", что необходимо по логике обработки.
(лестно осознавать, что мыслишь в одном направлении с профессионалом, только проблему "левых" значений в последнем элементе массива после выгрузки это все равно не решило)

Но мне все-таки удалось прикрыть "поролончиком" эти грабельки... :-))
(жаль только, что неизвестно - надолго ли?)

Когда в процедуру заполнения массива передается параметром имя курсора ( cCursorName ), то естественным образом где-то посреди ее текста там присутствует команда SELECT (cCursorName) ...
Так вот, когда я сразу же за ней поставил GO BOTTOM , то все без исключения массивчики сразу же стали заполняться "родными" значениями из нужного столбца.

Вот такие "пироги с котятами"...

З.Ы. как мне надоели уже эти фоксовые заморочки, когда код работает так "как было задумано" больше года и ВДРУГ оказывается, что может быть такое "сочетание звезд на небе", при котором он работать перестанет... или хуже того - начнет работать "выборочно"!!!
(это даже уже не бред, это просто - "смерть мухам")

З.Ы.Ы. Спасибо всем, принявшим участие в обсуждении... :-))
...
Рейтинг: 0 / 0
Глюк в конструкции SELECT ... INTO ARRAY
    #32504509
Crip
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
как мне надоели уже эти фоксовые заморочки
Вы думаете где-то по другому? Хорошо там, где нас нет...
...
Рейтинг: 0 / 0
14 сообщений из 14, страница 1 из 1
Форумы / FoxPro, Visual FoxPro [игнор отключен] [закрыт для гостей] / Глюк в конструкции SELECT ... INTO ARRAY
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]