|
удаление записей
|
|||
---|---|---|---|
#18+
Очень нужна помощь новичку. Я для отображения данных использую представление. Устанавливаю Код: plaintext 1.
В гриде (где отображается мое представление), добавляю 2 одинаковые записи (которые противоречат индексу Candidate). Если нажать на кнопку "сохранить", в которой содержится следующий код Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9.
А если сперва ввести 2 одинаковые записи, одну пометить на удаление, а потом "сохранить", то все нормально. Что я делаю не так. Раскажите, пожалуйста, как это надо делать. ... |
|||
:
Нравится:
Не нравится:
|
|||
26.05.2005, 16:44 |
|
удаление записей
|
|||
---|---|---|---|
#18+
Проблема с индексом заключается в том, что контроль уникальности происходит сразу в момент ввода данных в самом буфере . Т.е. еще ДО сброса буфера. В данном случае, ты не сможешь сдвинуть указатель записи со второй записи с дублирующим значением. Именно на нее и идет ругань. При этом не имеет никакого значение буферизирована таблица или нет. Т.е. здесь нужен перхват сообщения об ошибке, а не контроль записи по TableUpdate() (хотя он и не помешает, но это "вторичная", необязательная, проверка). Это одна из причин, почему я вместо контроля уникальности по индексу Candidat использую триггеры. В твоем случае простейшее решение, это сделать на базе таблицы Local View. Все остальное останется без изменений, но здесь контроль уникальности будет происходить именно в момент сброса буфера, а не ДО него. ... |
|||
:
Нравится:
Не нравится:
|
|||
26.05.2005, 17:27 |
|
удаление записей
|
|||
---|---|---|---|
#18+
ВладимирМ В твоем случае простейшее решение, это сделать на базе таблицы Local View. Все остальное останется без изменений, но здесь контроль уникальности будет происходить именно в момент сброса буфера, а не ДО него. Я и использую Local View. ВладимирМ В данном случае, ты не сможешь сдвинуть указатель записи со второй записи с дублирующим значением. Именно на нее и идет ругань А вот по записям я почему-то спокойно хожу (несмотря на то, что я ввела несколько дублирующих). Это в моей форме. А если просто открыть представление, тогда действительно не дает сдвинуть указатель. У меня 2 вопроса: 1. Почему у меня в форме не выдается сообщение об ошибке, а позволяет делать, все что мне вздумается? 2. На каком событии я должна перехватывать ошибку? И какой ее код? Заранее благодарна за ответы. ... |
|||
:
Нравится:
Не нравится:
|
|||
26.05.2005, 17:53 |
|
удаление записей
|
|||
---|---|---|---|
#18+
Видимо, на глупые вопросы никто не отвечает. ... |
|||
:
Нравится:
Не нравится:
|
|||
26.05.2005, 18:18 |
|
удаление записей
|
|||
---|---|---|---|
#18+
Хоть никто и не отвечает, осмелюсь задать еще один вопрос по аналогичной теме. Есть таблица "zakaz" , у которого индекс id_zak типа Primary. На базе него есть Local View "look_zak". При пометке записи на удалении в представлении - помечается запись и в таблице. Тут все нормально. Но при recall записи в представлении - ошибка: Uniqueness of index id_zak is violated. (1884) Объясните, пожалуйста, почему так происходит. ... |
|||
:
Нравится:
Не нравится:
|
|||
26.05.2005, 20:00 |
|
удаление записей
|
|||
---|---|---|---|
#18+
Так. С самого начала. Есть таблица с индексом типа CANDIDAT ... FOR !Deleted() На ее базе создано обновляемое Local View Редактирование этого Local View осуществляется в режиме табличной буферизации Сброс изменений осуществляется только по команде TableUpdate() БЕЗ транзакции Начну с конца. Хотя кажется, что при табличной буферизации сброс изменений во всех строках по команде TableUpdate() происходит сразу. Одним пакетом. Но на самом деле это не так. Сброс изменений происходит по одной записи за раз. Сбросили одну запись, если ошибок нет перешли к следующей. Сбросили и эту запись, если возникла ошибка, то не произошел сброс только этой самой записи на которой возникла ошибка и всех последующих. До которых еще не добрались. НО! Те записи, которые были сброшены до возникновения ошибки успешно сохранились в исходной таблице. Т.е. в твоем случае завели в Local View 2 одинаковые записи. Команда TableUpdate() вернула .F., но ошибка произошла при попытке сброса второй записи. А первая была успешно сброшена в исходную таблицу! Ты возвращаешся в GRID. НО! Тут очередная "подлянка". Ведь Local View ты не обновила, хотя частичный сброс данных произошел. И тут весь вопрос в том, какую именно запись ты пометишь как удаленную. Если ту, которая уже была сброшена, то это без толку. Вместо возможных 2 дублей получишь 3 дубля (одна уже в таблице и 2 в Local View). А вот если вторую, то проблем быть не должно, но только в том случае, если первую не редактировали. Вобщем - это надо отдельно на примерах показывать. Но проблема именно в том, что TableUpdate() частично успел сбросить записи в исходную таблицу. Как это предотвратить? Очень просто. Надо окружить сброс буфера транзакцией. Примерно так: Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11.
Транзакция и обеспечит факт сброса всех изменений из буфера "одним пакетом". Т.е. либо все, либо ничего. Однако в данном случае хорошо бы еще и самостоятельно проверить на предмет наличия дублей ДО попытки сброса. Дело в том, что такая "откаченная" буферизация не очень хорошо себя ведет при повторной попытке сброса. Возможны глюки. Еще один момент. Тебе кажется, что если внесены изменения в Local View, а потом эти изменения были успешно сброшены в исходную таблицу, то содержимое Local View и исходной таблицы стало одинаково. На самом деле это не так! Причин множество. Для "синхронизации" содержимого необходимо сделать обновление Local View после сброса буфера. Т.е. где-то так: Код: plaintext 1. 2.
Отсутствие обновления (синхронизации) Local View и может стать причиной нарушения уникальности Primary Key. Т.е. вместо снятия метки с записи, ранее помеченной как удленная юудет предпринята попытка создания новой записи . А это и вызовет подобное сообщение об ошибке. ... |
|||
:
Нравится:
Не нравится:
|
|||
26.05.2005, 23:28 |
|
удаление записей
|
|||
---|---|---|---|
#18+
Спасибо за разъяснения. Пробую. Но у меня еще один вопрос возник. Я на базе таблицы делаю прелставление. Если в таблице есть помеченные на удаление записи, представление их отображает все равно не помеченными. Как это понимать??? Еще немного, и я сойду с ума... ... |
|||
:
Нравится:
Не нравится:
|
|||
27.05.2005, 14:01 |
|
удаление записей
|
|||
---|---|---|---|
#18+
Так, предыдущий вопрос снимается. Простите. Ведь представление делается запросом SQL. При установке set deleted on помеченные записи не отображаются. Тогда вопрос такой: если пользователь удалил запись (сделал пометку), а потом опомнился и решил ее вернуть (по идее надо просто отрекалить), то как это сделать? Или пусть заново вводит? ... |
|||
:
Нравится:
Не нравится:
|
|||
27.05.2005, 14:54 |
|
удаление записей
|
|||
---|---|---|---|
#18+
k_svТогда вопрос такой: если пользователь удалил запись (сделал пометку), а потом опомнился и решил ее вернуть (по идее надо просто отрекалить), то как это сделать? Или пусть заново вводит? Пусть заново вводит! Дело в том, что восстановить запись помеченную как удаленная - это не такой простой процесс как кажется. Точнее, в простых случаях такое допустимо. Но представьте себе, что было выполнено каскадное удаление ряда записей. Например, при удалении шапки накладной надо удалить и все записи из накладной. Если пользователь передумал, то что, организовывать каскадное восстановление? А как быть с пересчетом сумм остатка? А если удаление затронуло больше таблиц? Да, в конце-концов, а как организовать поиск той записи, которую удалили? Ведь "шттатный" режим - это SET DELETED ON. Т.е. такие записи вообще не отображаются! И еще. Это ты знаешь, что процесс удаления разбит на 2 этапа: сначала установка метки на удаление, потом собственно физическое удаление. Но пользователь-то этого не знает! И не должен знать! Умерла, так умерла! ... |
|||
:
Нравится:
Не нравится:
|
|||
27.05.2005, 15:08 |
|
удаление записей
|
|||
---|---|---|---|
#18+
Спасибо за помощь. Но у меня очередная проблема и не могу понять в чем дело. Делаю все как и положено: ВладимирМ Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12.
Но первой же строчке выдается сообщение ошибка: Table v_tar_job has one or more non-structural indexes open. Please close them and retry the Begin Transaction (Error 1548) Но у меня никаких индексов-то нету... Что это может быть? Помогите, пожалуйста. ... |
|||
:
Нравится:
Не нравится:
|
|||
01.06.2005, 15:13 |
|
удаление записей
|
|||
---|---|---|---|
#18+
k_svНо первой же строчке выдается сообщение ошибка: Table v_tar_job has one or more non-structural indexes open. Please close them and retry the Begin Transaction (Error 1548) Но у меня никаких индексов-то нету... Что это может быть? Помогите, пожалуйста. Значит есть! Видимо, где-то в коде было построение индексов для View (команда INDEX). Закрой ЯВНО все открытые НЕ структурные индексы: Код: plaintext 1.
Можешь посмотреть что за индексы используя функцию ATAGINFO() - она появилась с 7 версии FoxPro. Для младших версий надо использовать TAGCOUNT() и NDX() ... |
|||
:
Нравится:
Не нравится:
|
|||
01.06.2005, 16:12 |
|
удаление записей
|
|||
---|---|---|---|
#18+
ВладимирММожешь посмотреть что за индексы используя функцию ATAGINFO() - она появилась с 7 версии FoxPro. Для младших версий надо использовать TAGCOUNT() и NDX() Нету индексов. TAGCOUNT('v_tar_job')=0 фукция ndx() возврацает пустую строку. У меня параметризованное представление. Или это без разницы? ... |
|||
:
Нравится:
Не нравится:
|
|||
01.06.2005, 16:48 |
|
удаление записей
|
|||
---|---|---|---|
#18+
Fox зря ругаться не будет. При появлении ошибки войди в Debugger и посмотри там (в коне Watch), что вернет функция TAGCOUNT('v_tar_job') Кстати, может не структурный индекс был построен по какой-либо другой таблице. Не обязательно по View. Сделай поиск по всему своему коду на предмет команды INDEX. ... |
|||
:
Нравится:
Не нравится:
|
|||
01.06.2005, 17:00 |
|
удаление записей
|
|||
---|---|---|---|
#18+
Да, действительно, были установлены структурные индексы на другое представление, использующее с моим общую таблицу. Да, самостоятельно со всеми тонкостями долго пришлось бы разбираться. Спасибо Вам огромное, ВладимирМ !!! ... |
|||
:
Нравится:
Не нравится:
|
|||
01.06.2005, 17:25 |
|
удаление записей
|
|||
---|---|---|---|
#18+
Недавно на практике столкнулся с ошибкой 1548 Table "alias" has one or more non-structural indexes open. Please close them and retry the Begin Transaction (Error 1548) Close all non-structural (non-.CDX) indexes and try the operation again. If other indexes are open on the file, their writes will go directly to disk and will not be reflected in the table changes until you issue END TRANSACTION. Consequently, if a ROLLBACK is issued, the non-structural indexes will be incorrect. Частично о данной ошибке также идет речь в http://]http://www.sql.ru/forum/actualthread.aspx?tid=332332&hl=1548 Таким образом вопрос заключается в том как "Close all non-structural (non-.CDX) indexes” В связи с чем возникла идея перед каждым вызовом Begin Transaction вызывать метод, либо процедуру, которая будет закрывать non-structural индексные файлы. Ничего лучшего чем нижеприведенный код мне придумать не удалось Для базового класса форм создаю два метода closeallnonstructuralindexes и Doesnonstructuralindexexist перед каждым вызовом Begin Transaction вызываю Thisform.closeallnonstructuralindexes() ** method closeallnonstructuralindexes Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27.
Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9.
Для обычных процедур соответсвенно перед каждым вызовом Begin Transaction Do Closeallnonstructuralindexes Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27. 28. 29. 30. 31. 32. 33. 34. 35. 36. 37. 38. 39. 40.
... |
|||
:
Нравится:
Не нравится:
|
|||
18.10.2008, 01:08 |
|
|
start [/forum/topic.php?fid=41&msg=33085964&tid=1587170]: |
0ms |
get settings: |
10ms |
get forum list: |
15ms |
check forum access: |
4ms |
check topic access: |
4ms |
track hit: |
63ms |
get topic data: |
10ms |
get forum data: |
2ms |
get page messages: |
53ms |
get tp. blocked users: |
1ms |
others: | 337ms |
total: | 499ms |
0 / 0 |