:: Visual Foxpro, Foxpro for DOS
Проблема с CursorFill(), а может и не с ним...
FoxProg
Автор

Сообщений: 150
Дата регистрации: 27.11.2012
Добрый день!
Много раз делал это, а тут вот обломился. Не могу понять в чем дело...
БД находится в MSSQL2005. Есть три таблицы pgrp_group, pgrp_tema и pgrp_date - список групп, каждая из которых имеет свой список тем, а каждая тема имеет свой список контрольных дат.
В каждой из таблиц есть уникальное поле id. Таблицы связаны между собой так, что
pgrp_tema.id_group=pgrp_group.id и
pgrp_date.id_tema=pgrp_tema.id
Есть три процедурки, которые извлекают данные с каждой из таблиц

ALTER PROCEDURE [dbo].[PGRPGroups]
@nIdCeh Integer =1
AS
BEGIN
SET NOCOUNT ON
SELECT id, id_ceh, ngroup, name_rus, name_eng, days_alarm
FROM pgrp_group
WHERE id_ceh=@nIdCeh
END

ALTER PROCEDURE [dbo].[PGRPTema]
@nIdGroup Integer =0
AS
BEGIN
SET NOCOUNT ON
IF @nIdGroup=0
SELECT id, id_group, npp, name_rus, name_eng, id_fam
FROM pgrp_tema
ELSE
SELECT id, id_group, npp, name_rus, name_eng, id_fam
FROM pgrp_tema
WHERE id_group=@nIdGroup
END

ALTER PROCEDURE [dbo].[PGRPDates]
@nIdTema Integer = 0
AS
BEGIN
SET NOCOUNT ON
IF @nIdTema=0
SELECT id, id_tema, date_contr, done FROM pgrp_date
ELSE
SELECT id, id_tema, date_contr, done FROM pgrp_date WHERE id_tema=@nIdTema
END

Вроде бы все проще не бывает.

Из VFP (9 SP2) подключаюсь к БД используя ADO.

Далее создаю форму и в Load прописываю
SET DELETED ON
SET TALK OFF
SET SAFETY OFF
SET CENTURY ON
SET DATE TO GERMAN
thisform.oGroups=CREATEOBJECT('ocad')
thisform.oGroups.Alias='pgrp_group'
thisform.oGroups.SendUpdates=.F.
thisform.oGroups.SelectCmd='exec PGRPGroups @nIdCeh=?ngIdCeh'
IF thisform.oGroups.CursorFill(.F., .F., 1, loCmd)=.F.
LOCAL laerror(1)
= AERROR(laerror)
MESSAGEBOX('pgrp_group '+STR(laerror(1))+' '+laerror(2))
RETURN .F.
ENDIF
nIdGroup=pgrp_group.id
thisform.oTema=CREATEOBJECT('ocad')
thisform.oTema.Alias='pgrp_tema'
thisform.oTema.SendUpdates=.F.
thisform.oTema.SelectCmd='exec PGRPTema @nIdGroup=?nIdGroup'
IF thisform.oTema.CursorFill(.F., .F., 1, loCmd)=.F.
LOCAL laerror(1)
= AERROR(laerror)
MESSAGEBOX('pgrp_tema '+STR(laerror(1))+' '+laerror(2))
RETURN .F.
ENDIF
GO TOP
nIdTema=pgrp_tema.id
thisform.oDates=CREATEOBJECT('ocad')
thisform.oDates.Alias='pgrp_date'
thisform.oDates.SendUpdates=.F.
thisform.oDates.SelectCmd='exec PGRPDates @nIdTema=?nIdTema'
IF thisform.oDates.CursorFill(.F., .F., 1, loCmd)=.F.
LOCAL laerror(1)
= AERROR(laerror)
MESSAGEBOX('pgrp_date '+STR(laerror(1))+' '+laerror(2))
RETURN .F.
ENDIF
GO TOP

ocad - класс созданный на базе CursorAdapter. В нем ничего особенного нету, пользуюсь им уже много лет і во многих программах. Если нужно, то опишу.
Что касается loCmd, то в главной программе
PUBLIC loСonn AS OBJECT, loCmd as ADODB.Command
*...
*loconn - соединение с MSSQL
*...
loCmd=CREATEOBJECT('ADODB.command')
loCmd.ActiveConnection=loConn
Для вывода информации на форму положил три грида соответственно для каждой таблицы grid1 -> pgrp_group, grid2 -> pgrp_tema и grid3 -> pgrp_date.

Для того, чтобы список тем обновлялся и соответствовал при изменении темы я для grid1 в AfterRowColChange прописал
LPARAMETERS nColIndex
nIdGroup=pgrp_group.id
thisform.otema.CursorRefresh()

И соответственно, чтобы список контрольных дат был соответствующим, в grid2 в AfterRowColChange прописал
LPARAMETERS nColIndex
nIdTema=pgrp_tema.id
thisform.odates.CursorRefresh()

Вроде бы что может быть проще и должно работать, но...
Когда я перемещаюсь вверх-вниз по 1-му гриду с группами, список тем обновляется нормально, перемещаюсь по 2-му гриду с темами, 3-й грид с контрольными датами тоже нормально обновляется. Но стоит мне вернуться на 1-й грид, как 2-й грид тут же становится пустым. Даже по второму гриду перемещаться не нужно, достаточно сделать его активным, а потом вернуться на 1-й и все - 2-грид уже путой.
Ratings: 0 negative/0 positive
Re: Проблема с CursorFill(), а может и не с ним...
ssa

Сообщений: 13007
Откуда: Москва
Дата регистрации: 23.03.2005
FoxProg
извлекают данные с каждой из таблиц
Вроде данные лежат В таблице, а не НА таблице, не так ли? Почему С, не ИЗ?
Цитата:

Из VFP (9 SP2) подключаюсь к БД используя ADO.
А можно узнать почему был сделан именно такой выбор?
Цитата:
Для того, чтобы список тем обновлялся и соответствовал при изменении темы я для grid1 в AfterRowColChange прописал
LPARAMETERS nColIndex
nIdGroup=pgrp_group.id
thisform.otema.CursorRefresh()
Если мне память не изменяет надо еще и соответствующие гриды обновлять.

------------------
Лень - это неосознанная мудрость.
Ratings: 0 negative/0 positive
Re: Проблема с CursorFill(), а может и не с ним...
FoxProg
Автор

Сообщений: 150
Дата регистрации: 27.11.2012
Да, у меня сначала было
thisform.grid2.Refresh
но я абсолютно все лишнее вычищал, чтобы получить минимальный код для нахождения ошибки, убрал и эту строку.
Что интересно, работает (если работает) и без этого рефреша.
Сейчас вернул, но ничего не изменилось.



Исправлено 1 раз(а). Последнее : FoxProg, 17.12.18 15:19
Ratings: 0 negative/0 positive
Re: Проблема с CursorFill(), а может и не с ним...
ssa

Сообщений: 13007
Откуда: Москва
Дата регистрации: 23.03.2005
FoxProg
Да, у меня сначала было
thisform.grid2.Refresh
но я абсолютно все лишнее вычищал, чтобы получить минимальный код для нахождения ошибки, убрал и эту строку.
Что интересно, работает (если работает) и без этого рефреша.
Сейчас вернул, но ничего не изменилось.
Без этого рефреша работает, но нестабильно и полностью затыкается при повторной пустой выборке.
А пока предлагаю проверить проходит ли CursorRefresh().


------------------
Лень - это неосознанная мудрость.
Ratings: 0 negative/0 positive
Re: Проблема с CursorFill(), а может и не с ним...
ssa

Сообщений: 13007
Откуда: Москва
Дата регистрации: 23.03.2005
Кстати, по поводу процедур и их необходимости. Текст каждой можно заменить на один запрос, на примере второй процедуры:
SELECT id, id_group, npp, name_rus, name_eng, id_fam
FROM pgrp_tema
WHERE id_group=@nIdGroup or @nIdGroup=0

Тут точно нужны именно процедуры?


------------------
Лень - это неосознанная мудрость.
Ratings: 0 negative/0 positive
Re: Проблема с CursorFill(), а может и не с ним...
FoxProg
Автор

Сообщений: 150
Дата регистрации: 27.11.2012
Разобрался...
У меня поля name_rus и name_eng имеют тип text. Изменил тип на nvarchar(255) и все заработало.
Не знал, что проблема будет в таком месте, ведь уже 100+1 раз использовал такой подход в своих программах.

Но меня это не устраивает. Название групп и тем могут иметь довольно большой размер. Не страница, конечно, но целый абзац может быть. Поставил пока nvarchar(MAX). Не знаю, что из этого получится и будет ли тип поля Memo в VFP соответствовать типу nvarchar(MAX) в SQL.

Проверил, да - соответсвует.
Тему можно закрывать. Всем спасибо!



Исправлено 1 раз(а). Последнее : FoxProg, 17.12.18 15:58
Ratings: 0 negative/0 positive
Re: Проблема с CursorFill(), а может и не с ним...
FoxProg
Автор

Сообщений: 150
Дата регистрации: 27.11.2012
ssa
Кстати, по поводу процедур и их необходимости. Текст каждой можно заменить на один запрос, на примере второй процедуры:
SELECT id, id_group, npp, name_rus, name_eng, id_fam
FROM pgrp_tema
WHERE id_group=@nIdGroup or @nIdGroup=0

Тут точно нужны именно процедуры?

Да, процедуры избыточны. Наверное дело привычки. Имеется в виду, что если параметр опущен, то должны быть выбраны все записи, а если есть, то только соответствующие параметру. Хотя в моей задаче параметр будет обязателен, но эти процедуры может будут использоваться друзими программами, где будет нужна выборка всех записей.

Хм... Да, Вы правы! Ваш пример красивый выверт (если есть такое слово)!
Ratings: 0 negative/0 positive
Re: Проблема с CursorFill(), а может и не с ним...
FoxProg
Автор

Сообщений: 150
Дата регистрации: 27.11.2012
Рано я кричал Ура...
Сегодян оказалось, что ничего не работает.
Тип поля varchar(MAX) подходит только к таблице pgrp_group.
Пока в таблице pgrp_tema не заменил МАХ на конкретное число работать не захотело. Поставил 1000. Хотя в фокс это поле передается, как MEMO, но все нормально работает.
Вот такое бывает.
Ratings: 0 negative/0 positive
Re: Проблема с CursorFill(), а может и не с ним...
ssa

Сообщений: 13007
Откуда: Москва
Дата регистрации: 23.03.2005
FoxProg
Тип поля varchar(MAX) подходит только к таблице pgrp_group.
Пока в таблице pgrp_tema не заменил МАХ на конкретное число работать не захотело.
Отсюда следует, что используется далеко не самый свежий драйвер доступа к серверу.

------------------
Лень - это неосознанная мудрость.
Ratings: 0 negative/0 positive
Re: Проблема с CursorFill(), а может и не с ним...
FoxProg
Автор

Сообщений: 150
Дата регистрации: 27.11.2012
Да, может быть...
У меня Windows 7, у многих пользователей ХР с драйверами, которые шли с инсталляцией.
Ratings: 0 negative/0 positive
Re: Проблема с CursorFill(), а может и не с ним...
ssa

Сообщений: 13007
Откуда: Москва
Дата регистрации: 23.03.2005
Это очень старые. На сайте мелкомягких есть значительно свежее, которые знают в том числе и про varchar(max)


------------------
Лень - это неосознанная мудрость.
Ratings: 0 negative/0 positive
Re: Проблема с CursorFill(), а может и не с ним...
FoxProg
Автор

Сообщений: 150
Дата регистрации: 27.11.2012
Компьютеры разбросаны по всему предприятию и я даже не знаю, сколько из них работают с этими программами. А главное - они все в домене и чтобы что-то установить нужен Администратор. Проще ограничить varchar(1000) - должно хватить.
Но как-то странно. Если брать только первые две таблицы (группы и темы или темы и контр.даты, группы и контр.даты не могу попробовать, т.к. они напрямую не связаны), то все работает нормально. Но как только задействуется третья таблица, у которой, кстати, нету varchar), то все валится. Вернее CursorFill отрабатывает правильно, а CursorRefresh нет.
Остановился на том, что ограничил во второй таблице длину полей 1000 символами.
Ratings: 0 negative/0 positive
Re: Проблема с CursorFill(), а может и не с ним...
Igor Korolyov

Сообщений: 34580
Дата регистрации: 28.05.2002
Я не понял, все 3 CAD используют один и тот же объект ADODB.Command? IMHO это неправильно.
Кроме того надо смотреть на всякие прогрессивные/асинхронные фишки адаптера (FetchSize, FetchMemo) - если он правильно пропихивает это в ADO (я лично с адо-коннекциями не работал, но мануал говорит что действуют), и тот начинает работать асинхронно, то попытка одновременно зарефрешить несколько CAD ничем хорошим не увенчается. По крайней мере для ODBC соединений FetchSize != -1 это большая проблема (занятости коннекции при одновременном извлечении данных в разные курсоры).


------------------
WBR, Igor
Ratings: 0 negative/0 positive
Re: Проблема с CursorFill(), а может и не с ним...
FoxProg
Автор

Сообщений: 150
Дата регистрации: 27.11.2012
Igor Korolyov
Я не понял, все 3 CAD используют один и тот же объект ADODB.Command? IMHO это неправильно.
Хм... Уже столько лет так использую и не только для 3-х, но и для гораздо большего количества. Всегда на всю программу использую один loCmd, который создав вначале в главном файле программы.
Наверное стоит изменить подход.

Igor Korolyov
Кроме того надо смотреть на всякие прогрессивные/асинхронные фишки адаптера (FetchSize, FetchMemo) - если он правильно пропихивает это в ADO (я лично с адо-коннекциями не работал, но мануал говорит что действуют), и тот начинает работать асинхронно, то попытка одновременно зарефрешить несколько CAD ничем хорошим не увенчается. По крайней мере для ODBC соединений FetchSize != -1 это большая проблема (занятости коннекции при одновременном извлечении данных в разные курсоры).
FetchSize=-1
FetchMemo=.T.
Первое пока не имеет значения, т.к. таблички пока совсем маленькие - до 20-ти записей.
Ratings: 0 negative/0 positive
Re: Проблема с CursorFill(), а может и не с ним...
FoxProg
Автор

Сообщений: 150
Дата регистрации: 27.11.2012
Сделал для каждого CAD свой loCmd и все прекрасно работает с любыми типами полей, включая и varchar(MAX). Правда с text не пробовал, но думаю, и там проблем не будет.
Всем спасибо за внимание и помощь!
Ratings: 0 negative/0 positive
Re: Проблема с CursorFill(), а может и не с ним...
ssa

Сообщений: 13007
Откуда: Москва
Дата регистрации: 23.03.2005
FoxProg
Сделал для каждого CAD свой loCmd и все прекрасно работает
А сделал бы ODBC, то вообще без loCmd обошелся бы...

------------------
Лень - это неосознанная мудрость.
Ratings: 0 negative/0 positive
Re: Проблема с CursorFill(), а может и не с ним...
Igor Korolyov

Сообщений: 34580
Дата регистрации: 28.05.2002
Да, для фокса выглядит несколько тяжеловесным использование АДО - если бы он ещё мог просто OleDb провайдеры напрямую использовать... А так - обёртка над обёрткой над обёрткой


------------------
WBR, Igor
Ratings: 0 negative/0 positive


Извините, только зарегистрированные пользователи могут оставлять сообщения в этом форуме.

On-line: 46 of63  (Гостей: 45)

© 2000-2024 Fox Club 
Яндекс.Метрика