Этот баннер — требование Роскомнадзора для исполнения 152 ФЗ.
«На сайте осуществляется обработка файлов cookie, необходимых для работы сайта, а также для анализа использования сайта и улучшения предоставляемых сервисов с использованием метрической программы Яндекс.Метрика. Продолжая использовать сайт, вы даёте согласие с использованием данных технологий».
Политика конфиденциальности
|
|
|
Вставка в таблицу записи с уникальным id
|
|||
|---|---|---|---|
|
#18+
Т.е. надо автоматически генерировать id для записей в таблице (по сути аналог счетчика в Access). Как это лучше сделать? Заранее благодарен! ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 26.12.2003, 12:19 |
|
||
|
Вставка в таблицу записи с уникальным id
|
|||
|---|---|---|---|
|
#18+
Делаешь поле типа int и когда запись добовляешь, то выбирай максимальный id и +1 Вот и все!!! ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 26.12.2003, 13:36 |
|
||
|
Вставка в таблицу записи с уникальным id
|
|||
|---|---|---|---|
|
#18+
авторкогда запись добовляешь, то выбирай максимальный id и +1 Очень даже вредный совет! Посмотри как сделано в сэмплах и в Tastrade - суть в наличии специальной системной таблицы, где хранятся "последние использованные" ключи для каждого такого автоинкрементного поля. И хранимая процедура, которая возвращает очередной ключик и наращивает соответствующий счётчик в системной таблице. Кстати в VFP8 есть AUTOINC модификатор для Integer полей, но по ряду причин я его не использую (в частности проблемы с представлениями на основе таблиц с AUTOINC). WBR, Igor ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 26.12.2003, 14:12 |
|
||
|
Вставка в таблицу записи с уникальным id
|
|||
|---|---|---|---|
|
#18+
FUNCTION NewId PARAMETERS cTableName select ids.next_id AS Next_n FROM ids ; WHERE ALLTRIM(UPPER(ids.table_name)) = ALLTRIM(UPPER(cTablename)); INTO CURSOR nexter nNewId = nexter.Next_n + 1 UPDATE ids SET next_id = nNewId WHERE ALLTRIM(UPPER(ids.table_name)) = ALLTRIM(UPPER(cTablename)) RETURN nNewId *ENDFUNC ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 26.12.2003, 14:46 |
|
||
|
Вставка в таблицу записи с уникальным id
|
|||
|---|---|---|---|
|
#18+
Тоже плохой пример - нужно явное управление блокировками - RLOCK() или уж на крайний случай FLOCK() для систенмной таблицы... В общем чего мучится то, всё уже есть, давно написано... WBR, Igor ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 26.12.2003, 15:49 |
|
||
|
Вставка в таблицу записи с уникальным id
|
|||
|---|---|---|---|
|
#18+
это ids блокировать надо? а зачем? что-то до сих пор не было проблем с доступом... Хотя может у Вас опыта больше... ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 26.12.2003, 16:41 |
|
||
|
Вставка в таблицу записи с уникальным id
|
|||
|---|---|---|---|
|
#18+
FM32YO__ это ids блокировать надо?Да. Его родимого и надо. автора зачем? что-то до сих пор не было проблем с доступом... Потому как при сетевой работе вполне возможна ситуация, когда в промежутке между SELECT и UPDATE с другой машины будет в свою очередь запрошен счётчик, и получится что 2 разные сессии получили один и тот-же ключ. Блокировка как раз гарантирует, что этого не произойдёт. Т.е. пока первая сессия не отлочит запись/таблицу а вторая сессия её не залочит - ничего читать/писать нельзя. То что это не слишком вероятно (ну компы нонче быстрые, юзеров много не сидит, да и интенсивность вставок новых записей как правило не очень большая) не означает, что это нужно игнорировать... WBR, Igor ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 26.12.2003, 17:22 |
|
||
|
Вставка в таблицу записи с уникальным id
|
|||
|---|---|---|---|
|
#18+
понял СПАСИБО! а не подскажете КАК малой кровью в моей функции єто проследить??? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 26.12.2003, 17:40 |
|
||
|
Вставка в таблицу записи с уникальным id
|
|||
|---|---|---|---|
|
#18+
Ну посмотри наконец на те хорошие примеры что я в самом начале заслал :( Tastrade и NewID из Solution-ов. Там хоть и не идеально но есть блокировка. WBR, Igor ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 26.12.2003, 17:56 |
|
||
|
Вставка в таблицу записи с уникальным id
|
|||
|---|---|---|---|
|
#18+
я тут подума - а с какой скоростью операторы должны наяривать данные чтобы свалить такой счетчик??? промежуток времени между select ids.next_id и UPDATE ИМХО настолько мал!!! Или Вы имеете в виду 500 операторов одновременно и в один момент.. не знаю как в РОССИИ но ИМХО нигде так не наяривают... = собственный опыт ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 26.12.2003, 17:56 |
|
||
|
Вставка в таблицу записи с уникальным id
|
|||
|---|---|---|---|
|
#18+
Део не в том наяривают или нет, а в том, что писать надо надёжно! Как говорится из ошибок встречаются чаще всего непредусмотренные :) WBR, Igor ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 26.12.2003, 18:04 |
|
||
|
Вставка в таблицу записи с уникальным id
|
|||
|---|---|---|---|
|
#18+
Большой скорости и не надо. При работе в сети нескольких (до 20 и более) пользователей у меня до того как явно стал применять RLOCK() такие ситуации были по разу в неделю точно. Сейчас работает вот это и проблем нет (кстати взял с TasTrade Solution) Код: 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. 41. 42. 43. 44. 45. 46. 47. 48. 49. 50. 51. 52. 53. 54. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 26.12.2003, 18:05 |
|
||
|
Вставка в таблицу записи с уникальным id
|
|||
|---|---|---|---|
|
#18+
2Igor Korolyov Покритикуй, давно я не занимался подобными вещами.. Не требуется ни обработки блокировок, ни дополнительных таблиц, но необходим индекс типа primary или candidate и имя тэга должно совпадать с именем поля, которое должно иметь тип Integer. Идея - в обработке ошибки 1884 (Uniqueness of index "name" is violated). Пример перегружен проверками, в работе я использовал более простую функцию (как давно это было!) Код: 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. 41. 42. 43. 44. 45. 46. 47. 48. 49. 50. 51. 52. 53. 54. 55. 56. 57. 58. 59. 60. Код: 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. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 27.12.2003, 12:44 |
|
||
|
Вставка в таблицу записи с уникальным id
|
|||
|---|---|---|---|
|
#18+
ставится фокс-8 и проблема решается сама собой, так как там есть поле integer(autoincrement) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 27.12.2003, 14:09 |
|
||
|
Вставка в таблицу записи с уникальным id
|
|||
|---|---|---|---|
|
#18+
Коллуги или я неверно пояснил.. или Вы неверно поняли.... в моем примере есть заранее созданная таблица ids [Next_id N(10,0), Table_name C(15)] 0 table1 0 table2 и так далее... в итоге при добавлении в таблицу1 или 2 строки Next_id меняется на 1, 2... 100 и так далее... или же все равно такой подход чреват проблемами? Верю у Вас опыта по-более чем у меня но НЕУЖТО при работе 2-5-10-20 юзеров одновременно возможен вариант, когда 3-е ОДНОВРЕМЕННО сделали Next_id = 5....??? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 27.12.2003, 21:40 |
|
||
|
Вставка в таблицу записи с уникальным id
|
|||
|---|---|---|---|
|
#18+
Запростец! Еще как бывает. Поэтому делать надо все по правилам. Как учит нас товарищ bdv9 или NNN. Cам делаю так как bdv9. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 28.12.2003, 11:24 |
|
||
|
Вставка в таблицу записи с уникальным id
|
|||
|---|---|---|---|
|
#18+
Ну мы тут и накрутили На практике я просто использую таблицу с последним номером. Далее пишу цикл, в котором пытаюсь ее открыть (EXCLUSIVE) Если не открывает, то выдается сообщение на 1 секунду - что пытается получить новый номер документа. И так 100 раз. После удачной попытки - это спец -таблица благополучно молча закрывается, а мы продолжаем работать... Может быть не так красиво и без обработки ошибок, но в сети при 30 пользователях работает вполне корректно... Но у каждого свой собственный путь и каждый должен в своей жизни написать подобный метод :) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 28.12.2003, 19:55 |
|
||
|
Вставка в таблицу записи с уникальным id
|
|||
|---|---|---|---|
|
#18+
Сколько тут уже написали ужас прям. Есть ещё вариант, уж если вы все налегаете на сетевую версию, то почему бы в качестве сервера не использовать SQL Server. Там все это продумано до мелочей. Если таблица для индивидуального пользования, то max(id)+1 - самый легкий вариант и ошибок здесь никаких быть не может. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 30.12.2003, 08:48 |
|
||
|
Вставка в таблицу записи с уникальным id
|
|||
|---|---|---|---|
|
#18+
> Если таблица для индивидуального пользования, то max(id)+1 - самый легкий вариант и ошибок здесь никаких быть не может. Не совсем. Даже совсем не так, если таблица будет более менее приличного размера :) Если уж таблица для индивидуального пользования, быстрее и проще всего старое доброе go (reccount()), затем id = id + 1 Ну а для многопользовательской среды, как уже отмечали выше, вариантов нет, только отдельная таблица идентификаторов (ключей) с блокировкой записей перед приращением идентификатора. Хотя и тут бывают глюки при большой нагрузке ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 30.12.2003, 15:39 |
|
||
|
Вставка в таблицу записи с уникальным id
|
|||
|---|---|---|---|
|
#18+
NNN Можно я за Игоря напоследок покритикую :)). Сомневаюсь я, что после нового года у меня будет время сюда заглядывать. Собственно по коду я особых ошибок не вижу (ну разве что стиль написания, но к делу это не относится). Меня смущает сам подход. Здесь идет не только генерация нового ключа, но и собственно создание новой записи (INSERT INTO) причем в определенном виде. Создается запись с Default-значениями и рассчитанным значением ключевого поля. Как следствие, это налагает определенный стиль написания процедуры вставки, что не есть хорошо. Например, при таком подходе организовать APPEND FROM невозможно. Придется писать циклы. Т.е. просто взять команду FoxPro и использовать ее уже не получится. Надо будет учитывать, а как эта команда будет увязана с принятой идеологией создания новых записей. Использование же служебной таблицы и вызов функции из Default-поля не налагает никаких ограницений на использование всех прочих команд FoxPro. XAndy1 Если уж таблица для индивидуального пользования, быстрее и проще всего старое доброе go (reccount()), затем id = id + 1 Далеко не факт, что последняя запись таблицы (GO (Reccount())) будет содержать и максимальное значение ключа записи. Это зависит от идеологии программы. Более надежным в этом случай будет все-таки работа с индексом (SET DELETED OFF + SET ORDER ... DESC + GO TOP) или определение MAX()+1 FM32YO aka KID "Если неприятность может случится, то она обязательно случится" (с) Если ты разрабатываешь процедуру для многопользовательского приложения (пусть даже для 2 клиентов), то почти наверняка возникнет ситуация, когда они одновременно обратятся к одной записи. Или в твоем случае влезут между SELECT и UPDATE Простейшая модификация твоего кода - это заменить SELECT на LOCATE и сразу после нее сделать попытку блокировки (RLOCK()). Соответсвенно заменить UPDATE на REPLACE (хотя это уже не обязательно). Ну, вот мой код для критики :) Здесь используется служебная таблица TabLists из базы данных Leasing следующей структуры TableName С(10) - имя таблицы (файла DBF) большими буквами LastID I - последнее использованное значение ключевого поля этой таблицы Код: 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. 41. 42. 43. 44. 45. 46. 47. 48. 49. 50. 51. 52. 53. 54. 55. 56. 57. 58. 59. 60. 61. 62. 63. 64. 65. 66. 67. 68. 69. 70. 71. 72. 73. 74. 75. 76. 77. 78. 79. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 30.12.2003, 18:25 |
|
||
|
Вставка в таблицу записи с уникальным id
|
|||
|---|---|---|---|
|
#18+
Есть вопрос!!! использую Ваш код в ХП.. на дефолт навесил функцию NewID - пока добавляю записи в режиме BROWSE все идет на УРА!!! А теперь... табличка из 2-х полей ID и name ворма в которой добавление записи делается так: Insert into MyTable (name) VALUES ("bla bla bla") итог - сообщение - Record is not locked и все... вот не пойму - я торможу или все же код? Еще раз повторюсь в режиме БРОУЗ в таблицу строки добавляются на ура и ИД номер аботает! ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 31.12.2003, 03:44 |
|
||
|
Вставка в таблицу записи с уникальным id
|
|||
|---|---|---|---|
|
#18+
2ВладимирМ Спасибо за критику :) С Наступающим! И надеюсь, что после нового года у меня будет время сюда заглядывать - либо шутка, либо временное явление :) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 31.12.2003, 09:36 |
|
||
|
Вставка в таблицу записи с уникальным id
|
|||
|---|---|---|---|
|
#18+
FM32YO aka KID Это вопрос по моему коду? Посмотри в отладчике, где именно происходит ошибка № 130 ("Record is not locked"). Сомневаюсь я, что в служебной таблице (т.е. в моем коде), поскольку у меня нет прямых команды REPLACE предварительно не обрамленных RLOCK(). Вероятно все-таки в той таблице, куда ты пытаешься сделать вставку (MyTable). А это может быть, если заголовок таблицы заблокирован другим процессом (при вставке автоматически блокируется заголовок таблицы, т.е. запись с номером 0). Для проверки выйди из FoxPro, снова войди, и дай команду INSERT, когда еще ничего не успел сделать NNN Мне тут придется разбираться с Axapt-ой, так что на пару месяцев я точно из FoxPro выпаду. Ну а по весне станет ясно насколько это затянется. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 31.12.2003, 10:30 |
|
||
|
Вставка в таблицу записи с уникальным id
|
|||
|---|---|---|---|
|
#18+
2 ВладимирМ Это я проверил в ПЕРВУЮ очередь!!! Ошибка происходит именно в строке INSERT INTO MyTable.... и НИЧЕМ таблица не может быть занята.. так как тестирую на простенькой форма, в окружении которой только ДВЕ таблицы - та, в которую вставляю запись и та, в которой для 1-й хранится последнеее значение ИД-номера.... так что если у ВАС это работает = чего-то я недоглядел.. вот пока не знаю чего именно.... ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 03.01.2004, 22:14 |
|
||
|
Вставка в таблицу записи с уникальным id
|
|||
|---|---|---|---|
|
#18+
прикольно сделал как Вы сказали - вышел - зашел и в коммандном окне INSERT INTO statusb (opis) VALUES ("t1") запись прошла.... неужто причина в том, что в форме у меня листбокс, RowSource для которого есть statusb_q.opis, где statusb_q есть SELECT * FROM statusb WHERE statusb.del_no = 1; INTO CURSOR statusb_q ORDER BY opis (код лежит в активэйте формы.....) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 03.01.2004, 22:23 |
|
||
|
Вставка в таблицу записи с уникальным id
|
|||
|---|---|---|---|
|
#18+
А никто не пробовал написать простой COM сервер? И только у него получать всякие иды, мне кажется это самое надежное решение. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 06.01.2004, 04:16 |
|
||
|
Вставка в таблицу записи с уникальным id
|
|||
|---|---|---|---|
|
#18+
вернулся снова к собственному коду - свое самое родное... принимаю во внимание Ваши замечания по поводу того, что при работе нескольких юзеров возможно дублирование уникального номера.. ВОПРОС!!! А если я буду делать вставку новой записи так: Begin Transaction INSERT INTO...... END TRANSACTION по идее, пока один юзер делает добавление записи - другой не сможет... Может кто поделится соображениями ? И, какое сообщение по идее должен получить 2-й юзер, если 1-й еще не завершил транзакцию? Если сообщение системное - как его заменить на свое - Русское? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 08.01.2004, 09:06 |
|
||
|
Вставка в таблицу записи с уникальным id
|
|||
|---|---|---|---|
|
#18+
Думаю транзакция здесь не поможет. Насколько я знаю транзакция действует только для данного пользователя, а другой может делать что угодно. Советую все-таки перейти на создание уникального идентификатора для таблицы, используя дополнительный файл - это проверенная технология: работает давно и без сбоев. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 08.01.2004, 09:31 |
|
||
|
Вставка в таблицу записи с уникальным id
|
|||
|---|---|---|---|
|
#18+
Да мой метод и использует дополнительный файл-таблица с полями Next_id N(10), TableName C(10) то есть для каждой таблицы в БД есть строка в этой дополнительной таблице, и данные оттуда берутся FUNCTION NewId PARAMETERS cTableName select ids.next_id AS Next_n FROM ids ; WHERE ALLTRIM(UPPER(ids.table_name)) = ALLTRIM(UPPER(cTablename)); INTO CURSOR nexter nNewId = nexter.Next_n + 1 UPDATE ids SET next_id = nNewId WHERE ALLTRIM(UPPER(ids.table_name)) = ALLTRIM(UPPER(cTablename)) RETURN nNewId *ENDFUNC Но Гуру данного вфорума указали на возможность 2-х юзеров ОДНОВРЕМЕННО вызвать ХП NewId.... Или Ва имели в виду нечто иное? Дайте пример работающего кода если можно, а то все, что тут перечислялось так или иначе НЕ всегда работает... ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 08.01.2004, 10:34 |
|
||
|
Вставка в таблицу записи с уникальным id
|
|||
|---|---|---|---|
|
#18+
Собственно пример рабочего кода я уже приводил в этом топике. И у меня он работает везде, давно и без сбоев. В некоторых проектах (правда в тестовых) применял его в связке ХП+Default value. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 08.01.2004, 11:05 |
|
||
|
Вставка в таблицу записи с уникальным id
|
|||
|---|---|---|---|
|
#18+
попробовал так: Форма1 и форма2 абсолютно одинаковые только в форма1 на СОХРАНИТЬ Begin Trans Insert... . . Wait window "1111" END Trans thisform.release() В Форма2 на сохранить Begin Trans Insert... . . END Trans в итоге обе формs висят на єкране и "ждут " пока с 1-й не погашу Wait window Иными словами утверждение о том, что каждая транзакция касается только того пользователя, который ее начал - неверно... вот только посоветуйте КАК сделать при этом в форме2 системное сообщение "Подождите... ля ля ля..." ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 09.01.2004, 08:48 |
|
||
|
Вставка в таблицу записи с уникальным id
|
|||
|---|---|---|---|
|
#18+
Сегодня проверил. Действительно ты прав. Может можно и так. <вот только посоветуйте КАК сделать при этом в форме2 системное сообщение "Подождите... ля ля ля..." Не знаю, но попробуй пойти не через транзакции, а через RLOCK() Код: 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. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 09.01.2004, 09:55 |
|
||
|
Вставка в таблицу записи с уникальным id
|
|||
|---|---|---|---|
|
#18+
огромное спасибо! Дома опробую... хотя... заранее знаю, что проджект мой будет юзать только 1 юзер.... просто на будущее интересуюсь.... ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 09.01.2004, 10:24 |
|
||
|
Вставка в таблицу записи с уникальным id
|
|||
|---|---|---|---|
|
#18+
Это правильно. Понравилась фраза с foxclub: "Стели солому направо и налево" . ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 09.01.2004, 11:11 |
|
||
|
Вставка в таблицу записи с уникальным id
|
|||
|---|---|---|---|
|
#18+
LOCAL t1, t2, t3, t4, Co1, Co2 t1 = ALLTRIM(UPPER(thisform.t1.value)) t2 = ALLTRIM(UPPER(thisform.t2.value)) t3 = thisform.t3.value t4 = thisform.t4.value Co1 = thisform.Co1.value Co2 = thisform.Co2.value private lError lError = .f. SET REPROCESS TO automatic &&20 begin transaction on error lError = .T. INSERT INTO Tovar (name, code, price, idgroup, idunits, Quantity, del_no) ; VALUES (t1, t2, t3, Groups_q.id, Units_q.id, t4, 1) wait window " 1111 " on error if lError ROLLBACK =messagebox("Повторите еще раз") else END TRANSACTION endif thisform.release() ******************************* такой Вариант порекомендовал Сергей Титов... все четко работает НО если 1-й юзер "держит" транзакцию... посредством wait window " 1111 " в моем примере... (сам понимаешь в реальной задаче wait window " 1111 " не будет присутствовать.. я его добавил исключительно в целях эксперимента... как же мне иначе симулировать "занятость" записи.. если я тест провожу один..) 2-й юзер при таком раскладе - SET REPROCESS TO automatic получает "видимость" того, что форма попросту "зависла" лично я никак на глаз не мог определить... то ли винда висит.. то ли прога... ну иллюзия зависания полная.... вот интересно КАК бы это обойти???? Если поставить SET REPROCESS TO 1 то есть одна и только одна попытка то 2-й юзер естественно сразу получит в лоб сообщением "Повторите еще раз" и форма закроется.... Дело в том, что в теперешней моей задаче форма ввода данных содержит примерно 30 контроллов... естественно юзер, заполнив их будет очень "рад" потерять все набранное из-за того, что другой юзер в это время что-то добавляет я базу... разве что НЕ закрівать форму в случае неудачного доступа к залоченной таблице... ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 09.01.2004, 11:52 |
|
||
|
Вставка в таблицу записи с уникальным id
|
|||
|---|---|---|---|
|
#18+
Очень кратко, пока не началось... :) Ошибка №130 (также, как и 108 и 109) связана с конфликтом совместного доступа. Наиболее вероятная причина - это некорректное использование PrivateDataSession. Помню, когда-то давно у меня такие ошибки были. Но как не пытался, но добиться того же эффекта с моим NewID() у меня не получилось. Транзакция. Необходимо стремиться к тому, чтобы время открытой транзакции было сведено к минимуму. Дело в том, что открытая транзакция блокирует все области, которые были изменены пользователем до завершения транзакции. А это много чего. Так сразу все и не перечислешь. Например, может быть заблокирован ВЕСЬ структурный индексный файл. Общая логика модификации и записи данных примерно следующая: -) Накладывается буферизация на таблицы источники -) Выполняется модификация в буферах -) А вот сам процесс сброса данных из буфера в исходные таблицы обрамляется транзакцией. При такое идеологии в случае отката транзакции (по разным причинам) система возвращается в то состояние, в котором она была до момента открытия транзакции. Т.е. к моменту уже заполненного, но еще не сброшенного буфера. Соответсвенно пользователь может повторить попытку сброса буфера без повторного ввода данных. Ну что-то вроде: =CURSORSETPROP('buffering',3,'MyTable') INSERT INTO MyTable (Field1) VALUES (1) BEGIN TRANSACTION IF TableUpdate(.T.,.T.,'MyTable') END TRANSACTION ThisForm.Release() ELSE ROOLBACK MessageBox('Сохранить не удалось. Повторите попытку') ENDIF ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 13.01.2004, 18:32 |
|
||
|
Вставка в таблицу записи с уникальным id
|
|||
|---|---|---|---|
|
#18+
This is the function I use to generate the Integer type Primary Keys for my tables.Requires a NextKey.dbf table. Enjoy: Код: 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. 41. 42. 43. 44. 45. 46. 47. 48. 49. 50. 51. 52. 53. 54. 55. 56. 57. 58. 59. 60. 61. 62. 63. 64. 65. 66. 67. 68. 69. 70. 71. 72. 73. 74. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 30.01.2004, 00:21 |
|
||
|
Вставка в таблицу записи с уникальным id
|
|||
|---|---|---|---|
|
#18+
2 sparrow Я делал COM для раздачи "инвентарных" номеров (реестровых). Но там проблема несколько отличалась. Дело в том, что требуемый номер должен был быть уникальным в пределах базы данных, а не только одной таблицы, как в случае с PK. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 30.01.2004, 11:05 |
|
||
|
Вставка в таблицу записи с уникальным id
|
|||
|---|---|---|---|
|
#18+
Rosty Vygovsky, Lynbrook, NY Видимо Вам тяжело читать по русски, но Ваш код повторяет целый ряд типичных ошибок. Он, конечно, работоспособный, но при очень определенных условиях. Посмотрите мой код страницей раньше. Там в комментариях я написал почему и зачем делал кое-какие дополнительные команды, которых нет в Вашем коде. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 30.01.2004, 14:59 |
|
||
|
Вставка в таблицу записи с уникальным id
|
|||
|---|---|---|---|
|
#18+
Господа, объясните мне, как работает foxpro в случае, когда индексы беруться из специальной таблицы, как предлагает, например, Igor Korolyov. Насколько я понимаю, алгоритм следующий: 1. Сеанс пользователя НЕ в режиме транзакции. 2. Сеанс выполняет оператор Insert Into... 3. СУБД открывает транзакцию. 4. Срабатывает триггер Insert Row, который берёт из специальной таблицы значение ключа. Значение ключа в специальной таблице увеличивается на 1. 5. Полученное значение ключа записывается туда, куда надо. 6. Транзакция закрывается. Далее: Если в этот же момент другой пользователь выполняет те же действия с небольшим запозданием, т.е. если его п.4 приходится на п.5 первого пользователя, он получит то же значение ключа, что и первый. В результате возникнет та же коллизия дублирования ключей. Или foxpro работает как-то по-другому? Спасибо. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 02.02.2004, 16:31 |
|
||
|
Вставка в таблицу записи с уникальным id
|
|||
|---|---|---|---|
|
#18+
to dasistgut п.4 второго юзера никогда не пересечется с п.5 первого, потому что, когда второй юзер дойдет до п.3, его программа "зависнет" и будет ждать, пока первый юзер не закончит п.6 Или в других БД транзакции работают как-то по-другому? ;) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 02.02.2004, 18:11 |
|
||
|
Вставка в таблицу записи с уникальным id
|
|||
|---|---|---|---|
|
#18+
dasistgut Все несколько не так. Значение ключа генерится не триггером, а несколько раньше, при генерации Default значения поля. Хотя для разбора полетов это не столь принципаильно. Дело в том, что открытая транзакция запрещает снимать блокировки установленные любым способом до завершения транзакции. Применительно к генерации ключа - это означает, что как только в служебной таблице была дана команда LOCK(), то даже последующий UNLOCK не снимет блокировку до закрытия транзакции. Т.е. другой пользователь не сможет сгенерить ключ, пока первый не разберется с транзакцией. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 02.02.2004, 18:17 |
|
||
|
Вставка в таблицу записи с уникальным id
|
|||
|---|---|---|---|
|
#18+
andrew_Pr Похоже, что в других БД транзакции действительно работают по-другому. Делаем простой проект: Delphi+IB. На любую таблицу вешаем примерно такой триггер: CREATE TRIGGER SET_EMP_NO FOR EMPLOYEE ACTIVE BEFORE INSERT POSITION 0 AS declare variable i integer; BEGIN i = 1; if (new.first_name = '1') then While (i>0) do begin i = i + 1; end END т.е. если поле first_name инициировано значением '1', то триггер зациклится. В программе одна форма, на которой DBGrid, с этой таблицей. Запускаем две копии программы. В первой вставляем запись с first_name = '1' и делаем Post. Прога "виснет", как и следовало ожидать. Во второй копии вставляем запись с first_name <> '1'. Запись вставляется и эта (вторая) прога продолжает работать нормально. Т.е. возвращаясь к моему вопросу, юзер на п.3 (по крайней мере в IB, Oracle) не зависнет. Но учитывая объяснение Владимира М становится всё понятно. Спасибо. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 03.02.2004, 00:15 |
|
||
|
Вставка в таблицу записи с уникальным id
|
|||
|---|---|---|---|
|
#18+
Очень полезный топик, хотя и несколько разросшийся:) Но по моему надо упоминуть и про такую вещь, как проверка неиспользованных ключей. вот что я имею ввиду: У меня, как и у большинства(я думаю), есть таблица с номером(integer) последнего ключа, так вот рано или поздно его значение станет огромным и при этом многие из уже использованных ключей освободились(например соответсвующая запись удалена). Тогда можно спокойно, например один раз в несколько месяцев, запускать процедуру проверки ключей, которая будет все положительные целые числа меньшие значения в таблице загонять во временную таблицу. Т.о. получаем дополнительные ключи, дальше можно например брать ключи из этой временной таблицы пока она не пустая. Если я в чем не прав поправьте меня. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 05.05.2004, 11:00 |
|
||
|
Вставка в таблицу записи с уникальным id
|
|||
|---|---|---|---|
|
#18+
>Тогда можно спокойно, например один раз в несколько месяцев, запускать >процедуру проверки ключей, которая будет все положительные целые числа >меньшие значения в таблице загонять во временную таблицу. Естественно имелись ввиду те значения которые ни где не используются. Это будет долгая процедура, не спорю. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 05.05.2004, 11:02 |
|
||
|
Вставка в таблицу записи с уникальным id
|
|||
|---|---|---|---|
|
#18+
Что значит "станет огромным"? Предельно допустимое количество записей в DBF-таблице - это 1 billion (единица и девять нулей) В типе Integer как правило используются только положительные значения, т.е. используется диапазон от 0 до 2,147,483,647 Значит, не боясь переполнения, можно совершенно спокойно удалить 2,147,483,647 - 1,000,000,000 = 1,147,483,647 записей Если каждый день без перерывов на выходные и праздники удалять по 10,000 записей, то для переполнения нам понадобиться: 1,147,483,647/(365*10,000) = 314 лет Ваша программа столько проживет? Так что, не обращайте внимание на "дыры" в нумерации. Не стоящее это занятие. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 05.05.2004, 12:01 |
|
||
|
|

start [/forum/topic.php?all=1&fid=41&tid=1596673]: |
0ms |
get settings: |
9ms |
get forum list: |
13ms |
check forum access: |
4ms |
check topic access: |
4ms |
track hit: |
47ms |
get topic data: |
13ms |
get forum data: |
3ms |
get page messages: |
97ms |
get tp. blocked users: |
2ms |
| others: | 221ms |
| total: | 413ms |

| 0 / 0 |
