Странно работает курсорадаптер | |
---|---|
Sandwich Автор Сообщений: 137 Дата регистрации: 08.02.2014 |
Всем здравствуйте.
битых 2 часа пытаюсь решить такую проблему: Создал курсорадаптер, через ODBC подключенный к БД MySQL.Buffer mode override=Optimistic row buffering Попытка в run-time изменить содержимое поля в курсоре не приводит к изменению в БД. Пробовал и через replace+go top и через update where. Причем в design-time (из командной строки и ручками в окне BROWSE) все работает корректно. Добавление строк (insert) нормально работает и в run-time и в design-time. |
Re: Странно работает курсорадаптер | |
---|---|
Igor Korolyov Сообщений: 34580 Дата регистрации: 28.05.2002 |
Вообще-то стоит использовать табличный режим буферизации и явное сохранение по tableupdate() - с проверкой сработало оно или нет - и если нет, то по какой причине через aerror()
А так - полное отсутствие кода никак не способствует помощи Можно лишь предположить что в IDE и в рантайме разные установки действуют, и какие-то из них влияют на процесс... При том что сам CAD, возможно, не полностью настроен - например не используется схема. ------------------ WBR, Igor |
Re: Странно работает курсорадаптер | |
---|---|
Sandwich Автор Сообщений: 137 Дата регистрации: 08.02.2014 |
Я мог бы привести полный текст replace или update, но сомневаюсь что это что-то прояснило бы В проекте полтора десятка CAD, все построены одинаково (схема используется) и работают корректно (кроме этого) А вот это дало положительный результат. В чем может быть причина? Глюк? |
Re: Странно работает курсорадаптер | |
---|---|
Igor Korolyov Сообщений: 34580 Дата регистрации: 28.05.2002 |
Интересует не replace/update меняющий курсор, а код задающий CAD - все его свойства/настройки. Именно это определяет как именно изменённые данные из курсора управляемого CAD передадутся в таблицу на сервере.
Если явный tableupdate помог, то осталось: - привести таки код описания CAD - имена полей можно заменить на "незначащие", главное сохранить ВСЕ настройки адаптера. - показать какой именно tableupdate помог - его параметры. - проверить действительно ли курсор находится в 3 режиме буферизации, или всё же каким-то кодом переведен в 5-й, и ни о каком "самостоятельном" сбросе изменений на сервер речи идти уже не может (хотя если insert проходит, то дело скорее всего не в этом). - проверить структуру курсора, её соответствие структуре в CAD и структуре в серверной таблице. Особое внимание обратить на char/varchar поля, их размеры, наличие "хвостовых пробелов" на сервере, и, возможно ConversionFunc. Аналогично для числовых полей - особенно с дробной частью. Ошибки в этих настройках будут приводить к тому, что при попытке обновить данные фокс сгенерирует такую SQL команду, которая "не узнает" исходную строку - скажем фокс сгенерирует команду update tbl set ... where id = csr.id and name = csr.name and salary = csr.salary на сервере в varchar поле name будет "чистое", без хвостовых пробелов значение "Вася", а в поле salary числовое значение, к примеру, 12345.678 - а у тебя в фоксе поле name указано как C(20) - т.е. дописывает кучу ненужных пробелов к значению, а поле salary имеет тип N(10,2) - и "теряет" младший разряд числа. Естественно подобная update команда ничего на сервере не обновит. Тогда как указав в tableupdate второй параметр как .T. ты автоматом "выкинешь" из генерируемой команды оба условия по name и salary, оставив там лишь поиск по id - и всё волшебным образом "заработает". P.S. Вообще крайне не советую использовать "автоматическое" сохранение данных из курсора при перемещении указателя записи - т.е. 3-й режим буферизации. Он неуправляем и практически неконтролируем. А вот в 5-м режиме, при явном tableupdate всё чётко и строго - и видно сразу прошло сохранение или нет, и можно посмотреть на причину/ошибку если оно неуспешно... Да и в общем само сохранение происходит не абы когда, а в строго определённый момент - например при нажатии кнопки сохранить, или при попытке закрытия формы редактирования. ------------------ WBR, Igor |
Re: Странно работает курсорадаптер | |
---|---|
Sandwich Автор Сообщений: 137 Дата регистрации: 08.02.2014 |
Дело было не в "бобине" Я долго не мог понять, почему обновление данных на сервере происходит ИНОГДА (в независимости от режима буферизации 3 или 5). И наконец-то нашел причину: проблема в поле типа Date. Если среди изменяемых полей его нет - все работает правильно. Если это поле есть - обновление не происходит (точнее не всегда). В БД это поле стоит NOT NULL и при добавлении новой строки оно заполняется '0000-00-00'. И если в момент обновления в поле стоит '0000-00-00', то обновления нет, если реальная дата (например '2018-05-14') - обновление происходит. БД моя - убрал NOT NULL - все стало работать корректно. НО 1. Что делать в такой ситуации, если менять структуру БД нельзя? 2. В Foxe теперь при пустых датах в Gride стоят NULL - некрасиво |
Re: Странно работает курсорадаптер | |
---|---|
ssa Сообщений: 12999 Откуда: Москва Дата регистрации: 23.03.2005 |
И при этом наверняка выскакивала ошибка 1526 с руганью сервера именно по этому поводу. Цитата:Научиться работать с null. ------------------ Лень - это неосознанная мудрость. |
Re: Странно работает курсорадаптер | |
---|---|
Sandwich Автор Сообщений: 137 Дата регистрации: 08.02.2014 |
Ну слава богу, хоть кто-то помог! Хоть кто-то разъяснил, чему надо учиться! Только Вы забыли добавить: Воспользуйся поиском. Одно не понятно: как же Вы, патриций, с нами плебеями на одном форуме? Не солидно как-то. |
Re: Странно работает курсорадаптер | |
---|---|
Igor Korolyov Сообщений: 34580 Дата регистрации: 28.05.2002 |
Так что прежде чем давать свои категоричные заключения, следует подумать над написанным. Ну и хамить не надо... ------------------ WBR, Igor |
Re: Странно работает курсорадаптер | |
---|---|
Sandwich Автор Сообщений: 137 Дата регистрации: 08.02.2014 |
Я не только подумал, но и проверил различные варианты настроек CAD, типа полей в серверной таблице и способов обновления. Конечно заработало, но таким способом без предупреждения "убьются" все данные, которые мог внести другой пользователь. Следующим логическим шагом д.б. второй параметр .F. и проверка по AERROR() и дальнейшие действия по результатам анализа полученной ошибки. Поэтому я повторю свой вопрос ещё раз: если в БД в поле date стоит NOT NULL, то tableupdate(1,.f.) при ConflictCheckType=3 генерирует ошибку 1585. Как исключить эту ошибку не прибегая к корректировке структуры БД и не "убивая" возможные чужие изменения путем tableupdate(1,.t.)? Если уж мой ответ (пусть и резкий) на такую пустую реплику SSA звучит хамски, то: Уважаемый SSA, примите извинения. |
Re: Странно работает курсорадаптер | |
---|---|
Igor Korolyov Сообщений: 34580 Дата регистрации: 28.05.2002 |
Если во внешней СУБД некоторое поле имеет значение по умолчанию, или любой иной вариант "автоматического заполнения" (например через триггер), то в фоксе следует использовать механизм обновления (рефреша) записей после вставки. Чтобы затянуть обратно те значения полей, которые были заданы на сервере (и чтобы данные в курсоре не отличались от данных на сервере после сохранения записи). К слову, если есть на сервере поля изменяемые при модификации записи (типа timestamp или "дата последнего изменения записи" заполняемая в триггере) то механизм рефреша следует применять не только к Insert, но и к Update командам. Это всё настраивается через группу свойств InsertCmdRefreshCmd, InsertCmdRefreshFieldList, InsertCmdRefreshKeyFieldList ну и аналогичная группа UpdateCmd* для рефреша после "модификации записи".
В зависимости от логики работы с курсором, может оказаться более простым/правильным не "рефреш" на уровне одиночных записей, а полный перезапрос (Requery) курсора после сохранения изменений из него на сервер (т.е. после tableupdate). Другой вариант, или, скорее, фикс некоторых подобных моментов - это всегда ЯВНО задавать в фоксовом курсоре значения для полей имеющих default value на сервере. Тогда фокс при insert отправит на сервер "своё" значение, и автоматика default value не будет работать. Но это не поможет, если "автомат присвоения" на сервере всё одно перезапишет пришедшее с клиента значение поля на своё - чаще всего это будет происходить при присвоении значений в триггере (не в курсе за MySQL, а в других СУБД это вполне обычная практика - правда аккуратно написанный триггер может и не "перебивать" значение, если оно явно было послано с клиента - ну и если оно не противоречит бизнес-логике). Ну и это не поможет для уже имеющихся в БД записей с "неправильными" значениями полей. Теперь конкретно к "пустым датам" - в фоксе недопустимо значение даты 0000-00-00 - его нельзя никак получить (всё что "раньше" 0000-03-00 хоть и "рисуется" как пустая дата, тем не менее таковой не является, что легко увидеть применив EMPTY() или сравнение с {} Во что "превращается" фоксовая пустая дата при посылке на внешний сервер - это уже нюансы реализации конкретных ODBC драйверов и конкретных серверов. В большинстве СУБД нет в принципе "пустой даты", в MSSQL, насколько я помню, фоксовая пустая дата преобразуется в совсем уж "непустую" 1900-01-01... В общем не следует использовать фоксовую пустую дату при работе с внешними СУБД. Если логика задачи позволяет, следует использовать NULL - настройка его отображения в фоксе достаточно гибкая - от "общего" SET NULLDISPLAY до "конкретных" свойств NullDisplay текстобоксов, спиннеров и ряда других элементов управления. Конечно же надо чётко понимать как "работает" NULL - в частности что это НЕ "пустая дата" и даже НЕ "значение", что сравнение поле=NULL или поле!=NULL являются некорректными... Если логику задачи под "правильный" NULL нельзя перевести, то следует выбрать какую-то определённую дату и считать это конкретное значение за "пустоту". При этом следует проверить, что эта дата корректно преобразуется между фоксом и используемой СУБД, и не создаёт проблем в других использующих эту БД программах (скажем для дат ранее 1601 года многие программы и даже среды программирования ведут себя некорректно - даже фокс "спотыкается" при SET DATE LONG/SHORT). Естетсвенно уже имеющиеся в БД даты "неправильного" вида следует исправить и привести к выбранному варианту. Т.е. дата 0000-00-00 для фокса - явно "не прокатит". ------------------ WBR, Igor |
Re: Странно работает курсорадаптер | |
---|---|
Sandwich Автор Сообщений: 137 Дата регистрации: 08.02.2014 |
Спасибо
Наверное все-таки не так: При работе из FoxPro с внешними СУБД, в которых поля типа Date установлены NOT NULL, следует иметь в виду, что возможна некорректная работа |
Re: Странно работает курсорадаптер | |
---|---|
Igor Korolyov Сообщений: 34580 Дата регистрации: 28.05.2002 |
Корректная работа с "пустой датой", даже если такое понятие и есть во внешней СУБД - весьма маловероятна. Соответственно фоксовая "пустая дата" и не должна использоваться. NULL/NOT NULL констрейн на поле (что во внешней БД, что в фоксовом курсоре) к этому прямого отношения не имеет - вероятно он лишь повляил на то что сервер какой-то свой аналог "пустой даты" стал в поле записывать. Я не знаком со спецификой MySQL, а в других СУБД попытка НЕ указать значение в момент вставки при наличии констрейна NOT NULL и отсутствии явного default value в поле (либо задания значения для этого поля в триггере) приведёт к ошибке и запись просто не будет создана вообще - никаких 0000-00-00 или иных "пустых дат" ни MSSQL, ни Oracle не подсунут.
Некорректная работа может быть и с непустыми датами - скажем с датами меньше 1601 года для некоторых СУБД. И, конечно, с полями datetime если их забирать в фоксовое поле типа date - обрезка "времени" тоже приведёт к подобным ошибкам для любой записи где время отлично от полуночи. По сути это false positive фоксовой ошибки "Update conflict" - т.е. фокс считает что данные во внешней БД изменились (т.к. они реально отличаются от тех данных которые у него в курсоре находятся). Хотя на самом деле проблема возникла в момент извлечения, когда данные были преобразованы и в процессе этого преобразования была "потеряна точность", или прилипли "хвостовые пробелы", или вот такие вот нюансы "пустоты непустых дат" возникли. ------------------ WBR, Igor |
Re: Странно работает курсорадаптер | |
---|---|
Sandwich Автор Сообщений: 137 Дата регистрации: 08.02.2014 |
Спасибо за развернутые ответы. Буду иметь эту инфу в виду при дальнейшей работе |
© 2000-2024 Fox Club  |