|
|
|
Буферизация и индекс кандидат
|
|||
|---|---|---|---|
|
#18+
Никогда не работал с буферизацией, и вот решил попробовать что же это такое. Всегда внесение новой строки или изменение данных в имеющейся вешал на отдельную форму, в которую пользователь вводил значения и,по кнопке "сохранить", делал необходимые проверки (или переключал контроль ошибок в режим "невидимый", т.е. чтобы пользователю не вываливалось сообщений об ошибках правил таблицы или нарушения уникальности индексов). Если ошибок нет - release`им форму, есть - сообщаем что не так, оставляем форму видимой, для дальнейшей правки. Тут по дизайнерской задумке решил разрешить вносить изменения прямо в основном гриде. Сделал табличную буферизацию (грид отображает кусок таблици по set key range). На выходе из формы повешал проверку на наличие изменений в буфере и tableupdate. Вот тут бы и воткнуть все необходимые мне проверки на корректность данных. Но. как всегда есть некое НО. При внесении изменений в строку данных и переходе на другую запись ругается на нарушении уникальности индекса. Индекс на основной таблице. Убирать его считаю неправильным (контроль превыше всего - и пусть он будет на уровне таблицы). Внимание вопрос. Как можно отловить подобную ошибку. В каких методах ее можно проверить (ну или в каком методе перехватить глобальный обработчик ошибок, чтобы не пришлось делать реверт таблицы) и остаться на той записи, которая вызывает ошибку уникальности ключа? PS понимание того, что индексы в памяти строятся даже на буферизованный кусок данных - есть. Проверку хотел прикрутить на lostfocus текстбокса колонки, в которой вносятся индексируемые данные. Но чтобы проверить надо по таблице "пройтись" в поисках дубля, а это в свою очередь вызывает уход с текущей записи и попытке перестроить индекс с последующей ошибкой уникальности. Открыть таблицу в другом алиасе, тогда данные внесенные в буфер первого алиаса видны не будут (а вполне вероятно, что данные уже в буфере изменены или внесены ДВЕ новые строки, которые и будут конфликтовать). Т.е. второй алиас тоже не вариант. Posted via ActualForum NNTP Server 1.4 ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 16.06.2008, 08:23 |
|
||
|
Буферизация и индекс кандидат
|
|||
|---|---|---|---|
|
#18+
В связи с отсутствием ответов, боюсь, что слишком сложно задал вопрос. :-) Поясню на примере, чего пытаюсь сделать: Открываем форму (прилагается). Тыркаем кнопку "Добавить", в новую запись заносим в поле year значение "1111". Переходим на другую запись. Получаем ошибку. Как (а главное где) ее правильнее отловить неотключая основной обработчик ошибок "on error" ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 16.06.2008, 11:55 |
|
||
|
Буферизация и индекс кандидат
|
|||
|---|---|---|---|
|
#18+
Само приложение. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 16.06.2008, 11:56 |
|
||
|
Буферизация и индекс кандидат
|
|||
|---|---|---|---|
|
#18+
рекомендую использовать курсорадаптер примеры использования КАДа с nativ источником приводились ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 16.06.2008, 12:55 |
|
||
|
Буферизация и индекс кандидат
|
|||
|---|---|---|---|
|
#18+
Судя по всему у Вас 3-я буфферизация если сброс происходит автоматически при переходе от строки к строке. Ставте 5-ю. Хотя это все равно не гарантирует от проблем с кандидат индексом. Если перешли на схему непосредственого ввода в Грид то проверяте поля по мере ввода - либо Valid/LostFocus теккстбоксов в колонках гридов или AfterRowColChange грида ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 16.06.2008, 14:43 |
|
||
|
Буферизация и индекс кандидат
|
|||
|---|---|---|---|
|
#18+
BurnСудя по всему у Вас 3-я буфферизация если сброс происходит автоматически при переходе от строки к строке. Ставте 5-ю. Хотя это все равно не гарантирует от проблем с кандидат индексом. Если перешли на схему непосредственого ввода в Грид то проверяте поля по мере ввода - либо Valid/LostFocus теккстбоксов в колонках гридов или AfterRowColChange грида Это не поможет. Контроль индекса осуществляется еще ДО сброса буфера. По факту заполнения записи. Т.е. и в табличном режиме буферизации будет выскакивать сообщение об ошибке при попытке перейти на другую запись. Единственный вариант в данном случае - это ручной перехват системной ошибки в событии формы Form.Error() или в аналогичном событии Grid.Error(). Код ошибки 1884. Проблема только в том, что если есть несколько индексов типа Candidat, то нет возможности однозначно определить, какой же из них вызвал ошибку. В принципе, Александр предложил правильное решение. Работать не напрямую с таблицей, а с выборкой (копией) из этой таблицы. Как эту копию организовать - через CursorAdapter, Local View, набор переменных или каким-нибудь еще способом - не важно. Важно, что работа будет осуществляться не с самой таблицей-источником (пусть и буферизированным), а с другими данными. Как правило, в реальных приложениях напрямую с исходными таблицами работают крайне редко. Другой вариант - это организовать контроль уникальности не через индекс, а через триггер на вставку. Вот триггер будет срабатывать только в момент сброса буфера. При определенных стандартах создания структуры базы данных можно написать универсальный (в рамках данной базы данных) триггер на контроль уникальности введенных данных. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 16.06.2008, 19:47 |
|
||
|
Буферизация и индекс кандидат
|
|||
|---|---|---|---|
|
#18+
> Судя по всему у Вас 3-я буфферизация если сброс происходит > автоматически при переходе от строки к строке. Ставте 5-ю. Хотя это все > равно не гарантирует от проблем с кандидат индексом. Так я же и говорю. стоит 5-я. проблемы с кандидат есть. > Если перешли на схему непосредственого ввода в Грид то проверяте поля > по мере ввода - либо Valid/LostFocus теккстбоксов в колонках гридов или > AfterRowColChange грида Спасибо за попытку совета, но если бы все было так просто. Во первых valid мне ничего не даст (надо сравнивать со значениями других строк). Во-вторых в AfterRowColChange - уже позно пытаться отловить ошибку нарушения уникальности - она уже произошла. Posted via ActualForum NNTP Server 1.4 ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 17.06.2008, 04:54 |
|
||
|
Буферизация и индекс кандидат
|
|||
|---|---|---|---|
|
#18+
> Единственный вариант в данном случае - это ручной перехват системной > ошибки в событии формы Form.Error() или в аналогичном событии > Grid.Error(). Код ошибки 1884. Перешел на строковую буферизацию с принудительным сбросом буфера в событии beforerowcolchange IF This.RowColChange= 1 OR This.RowColChange=3 AND GETFLDSTATE('Year','limits')>1 IF !TABLEUPDATE( 1, .t. , 'limits') NODEFAULT RETURN .f. ENDIF ENDIF Такой же механизм при попытке закрытия формы (т.е. самой таблицы) При таком раскладе сообщение не выскакивает, а можно обработать через четвертый параметр ф-ции tableupdate (пока еще не сделал) > В принципе, Александр предложил правильное решение. Работать не > напрямую с таблицей, а с выборкой (копией) из этой таблицы. > Как эту копию организовать - через CursorAdapter, Local View, набор > переменных или каким-нибудь еще способом - не важно. Важно, что работа > будет осуществляться не с самой таблицей-источником (пусть и > буферизированным), а с другими данными. Раньше работал только через переменные (в ините модифицирующей формы заполнял control.value, по кнопке "применить" - все необходимые проверки, в. т.ч. позволяющие пробегать по таблице источнику). А тут вот решил освоить что-то новое :) > Как правило, в реальных приложениях напрямую с исходными таблицами > работают крайне редко. Дык я так понимаю что буферыы ввели как раз для того, чтобы не напрямую с таблицами работать. > Другой вариант - это организовать контроль уникальности не через > индекс, а через триггер на вставку. Вот триггер будет срабатывать только в > момент сброса буфера. При определенных стандартах создания структуры базы > данных можно написать универсальный (в рамках данной базы данных) триггер > на контроль уникальности введенных данных. Индекс - это все таки индекс. Он и быстрее и надежнее отработает чем тригер. Posted via ActualForum NNTP Server 1.4 ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 17.06.2008, 05:15 |
|
||
|
Буферизация и индекс кандидат
|
|||
|---|---|---|---|
|
#18+
автор Дык я так понимаю что буферыы ввели как раз для того, чтобы не напрямую с таблицами работать. еще раз советую - возьмите КАД. там сделаете свой обработчик + будете использовать доп.курсор для ввода изменений + если необх-мо проверки делать у др.источника + получите локальный обработчик ошибки + получите правильные методы и события пример ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 17.06.2008, 09:08 |
|
||
|
Буферизация и индекс кандидат
|
|||
|---|---|---|---|
|
#18+
Galyamov Rinat > Единственный вариант в данном случае - это ручной перехват системной > ошибки в событии формы Form.Error() или в аналогичном событии > Grid.Error(). Код ошибки 1884. Перешел на строковую буферизацию с принудительным сбросом буфера в событии beforerowcolchange Код: plaintext 1. 2. 3. 4. 5. 6. Такой же механизм при попытке закрытия формы (т.е. самой таблицы) При таком раскладе сообщение не выскакивает, а можно обработать через четвертый параметр ф-ции tableupdate (пока еще не сделал) На практике, это единственно возможный способ работы, в случае прямой модификации данных в Grid. Ведь признаком завершения модификации как раз и является попытка перехода на другую запись. Значит, вне зависимости от типа буферизации (можно и 5 режим использовать) необходимо выполнить контроль введенных данных в событии Grid.BeforRowColChange() Galyamov Rinat Раньше работал только через переменные (в ините модифицирующей формы заполнял control.value, по кнопке "применить" - все необходимые проверки, в. т.ч. позволяющие пробегать по таблице источнику). А тут вот решил освоить что-то новое :) И это правильно! Даже если не получится использовать новый метод все-равно приобретете ценный опыт и новые знания. Galyamov Rinat > Как правило, в реальных приложениях напрямую с исходными таблицами > работают крайне редко. Дык я так понимаю что буферыы ввели как раз для того, чтобы не напрямую с таблицами работать. Не совсем. Цель буфера - это "развести" процесс внесения изменений (который может длится часами - пользователь вышел пообедать) и процесс сохранения внесенных изменений (который должен выполняться максимально быстро). Т.е. пользователь вносит изменения в некоторую копию данных, а сами исходные данные при этом остаются не изменными до момента сохранения внесенных изменений. Просто буферизация в FoxPro позволяет создать эту копию автоматически. У программиста нет необходимости создавать эту копию вручную. Ну, как Вы раньше создавали набор переменных. Однако прямая правка таблиц, пусть даже и буферризированных имеет ряд проблем. В частности при использовании индексов Primary и Candidad. Поэтому для редактирования все-таки создают копию данных, но не через набор переменных, а через запрос (Select-SQL). Этот запрос "оборачивают" в класс. В младших версиях FoxPro - параметризированное Local View, а начиная с VFP8 - класс CursorAdapter. При этом, при определенных настройках, изменения сделанные в Local View или CursorAdapter также автоматически будут "сбрасываться" в исходную таблицу. По сути, тот же "буфер", но другими средствами. Galyamov Rinat > Другой вариант - это организовать контроль уникальности не через > индекс, а через триггер на вставку. Вот триггер будет срабатывать только в > момент сброса буфера. При определенных стандартах создания структуры базы > данных можно написать универсальный (в рамках данной базы данных) триггер > на контроль уникальности введенных данных. Индекс - это все таки индекс. Он и быстрее и надежнее отработает чем тригер. Вопрос спорный и не однозначный. Впрочем, не думаю, что имеет смысл затевать дискуссию на эту тему. Кое-что на эту тему можно почитать здесь Контроль уникальности данных при помощи индекса ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 17.06.2008, 15:43 |
|
||
|
Буферизация и индекс кандидат
|
|||
|---|---|---|---|
|
#18+
А все же индексы типа Primary и Candidad, я всегда считал, что должны заполняться автоматом и нечего юзеру самому там ползать. Прописал в табличке в значении default value поля ссылку на Stored Procedures, где генерится уникальный индекс и забыл про это :D ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 17.06.2008, 15:59 |
|
||
|
Буферизация и индекс кандидат
|
|||
|---|---|---|---|
|
#18+
Плохой-советчикА все же индексы типа Primary и Candidad, я всегда считал, что должны заполняться автоматом и нечего юзеру самому там ползать. Прописал в табличке в значении default value поля ссылку на Stored Procedures, где генерится уникальный индекс и забыл про это :D Угу. Справочник контрагентов. Разумеется, названия контрагентов повторяться не должны. Разумеется, удаленные записи не должны включаться в контроль уникальности. Разумеется, легко написать Default Value, чтобы автоматом присвоить имя новому конрагенту. С Primary-индексом, как правило, проблем нет. Разумеется, если используются суррогатные ключи. Проблемы начинаются с индексами Candidad. Тут довольно много "но" и "если"... ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 17.06.2008, 16:07 |
|
||
|
Буферизация и индекс кандидат
|
|||
|---|---|---|---|
|
#18+
Трудно представить, что по названиям контрагента идет индекс, не правда ли? А если существует другой контрагент с тем же названием? Может тогда какое либо предупреждение выдать клиенту, типа существует контрагент с таким именем, вы уверены, что хотите завести нового с тем же именем. А если оператор занесет по разному одно и то-же предприятие? "Бриг" ООО и ООО "Бриг" :) Может такие вещи не стоит весить на индекс кандидат, а делать отдельную обработку? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 17.06.2008, 17:33 |
|
||
|
Буферизация и индекс кандидат
|
|||
|---|---|---|---|
|
#18+
прошу прощения за оффтоп И какие данные мне не приходят в голову, я их ни как не могу представить в гриде, только форма с текстовыми полями, данные по клиенту, коих немеряно и заносить их в гриде немерянной ширины - нет уж, увольте. Грид для поиска и удобной навигации, щелчек и выходиш в форму. Или в гриде править мелочевку некую. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 17.06.2008, 17:48 |
|
||
|
Буферизация и индекс кандидат
|
|||
|---|---|---|---|
|
#18+
> А все же индексы типа Primary и Candidad, я всегда считал, что должны > заполняться автоматом и нечего юзеру самому там ползать. > Прописал в табличке в значении default value поля ссылку на Stored > Procedures, где генерится уникальный индекс и забыл про это :D Ты не путай первичный ключ и индекс кандидат. Кандидат призван для контроля неповторяемости самих данных, тогда как первичный ключ - это ключ однозначно идентифицирующий набор данных (строку) Posted via ActualForum NNTP Server 1.4 ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 18.06.2008, 05:13 |
|
||
|
Буферизация и индекс кандидат
|
|||
|---|---|---|---|
|
#18+
> Автор: Плохой-советчик > И какие данные мне не приходят в голову, я их ни как не могу > представить в гриде, только форма с текстовыми полями, данные по клиенту, > коих немеряно и заносить их в гриде немерянной ширины - нет уж, увольте. Я тебя, в общем-то, и не заставляю программить грид на редактирование. Это во - первых. Во - вторых, ты же не видишь чего я редактирую, а уже критикуешь. Ну и плюс ко всему, есть грид, для просмотра. Все данные в него включены (т.е. по любому все поля НАДО показать пользователю). Так почему бы не дать пользователю возможность редактировать их прямо в гриде??? Полей действительно много - 37. 1 - I, 36 - N(12,3) т.е. довольно таки широкие. Но, не поверишь, они все совершенно спокойно помещаются в одну ширину экрана в гриде. Ведь в гриде данные можно отобразить и в несколько строк. Я посчитал, что мне достаточно 3-х. Итого у меня получается 13 колонок. 1 год и 12 месяцев. На каждый год/месяц - 3 строки. "Годов" может быть несколько для каждого объекта - поэтому ГРИД. Но для каждого объекта не может быть только одинаковых "ГОДОВ" - поэтому индекс кандидат. Posted via ActualForum NNTP Server 1.4 ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 18.06.2008, 05:25 |
|
||
|
|

start [/forum/topic.php?fid=41&msg=35375506&tid=1587652]: |
0ms |
get settings: |
7ms |
get forum list: |
17ms |
check forum access: |
3ms |
check topic access: |
3ms |
track hit: |
58ms |
get topic data: |
11ms |
get forum data: |
3ms |
get page messages: |
71ms |
get tp. blocked users: |
2ms |
| others: | 216ms |
| total: | 391ms |

| 0 / 0 |
