Этот баннер — требование Роскомнадзора для исполнения 152 ФЗ.
«На сайте осуществляется обработка файлов cookie, необходимых для работы сайта, а также для анализа использования сайта и улучшения предоставляемых сервисов с использованием метрической программы Яндекс.Метрика. Продолжая использовать сайт, вы даёте согласие с использованием данных технологий».
Политика конфиденциальности
|
|
|
Вставка в таблицу записи с уникальным 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?fid=41&msg=32507154&tid=1596673]: |
0ms |
get settings: |
8ms |
get forum list: |
16ms |
check forum access: |
3ms |
check topic access: |
3ms |
track hit: |
46ms |
get topic data: |
10ms |
get forum data: |
2ms |
get page messages: |
75ms |
get tp. blocked users: |
1ms |
| others: | 239ms |
| total: | 403ms |

| 0 / 0 |
