|
|
|
Помогите новичку (многие ко многим)
|
|||
|---|---|---|---|
|
#18+
Добрый день! Прошу помощи! У меня MSSQL 2000. Такя ситуация: Есть две таблицы "сотрудники" и "командировки" У каждой PK - это SMALLINT IDENTITY. Каждый сотрудник может быть во многих командировках и в одной командировке может быть много сотрудников, т.е. связь "многие ко многим". Эту связь разрешаю созданием третьей таблицы "командировка-сотрудник" в которой два поля id сотрудника id командировки. При записи информации о командировке мне необходимо выполнить следующие действия: 1. Вставить запись в табл. Командировки 2.Получить id этой записи 3. Вставить в таблицу связи столько записей сколько сотрудников едет в командировку(с id полученным в пункте 2) Понятно что это все одна транзакция. Такой вопрос: Как мне гарантировать что во втором пункте я получу именно тот id который мне нужно, т.е. что в этот момент никто другой не вставит запись в таблицу командировки и я получу следующий(не верный id)? Как это грамотно реализовать? Простите если это все бред. Спасибо. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 23.07.2002, 10:16:48 |
|
||
|
Помогите новичку (многие ко многим)
|
|||
|---|---|---|---|
|
#18+
Для этого существует две возможности: 1. Использование системной переменной @@IDENTITY, которая возвращает последнее значение поля IDENTITY, в которое производилась вставка в текущем сеансе. Не гарантирует, что вернет именно то значение (относящееся к нужной таблице), которое ты ожидаешь получить, т.к. возможно, что существует триггер, в котором осуществляется вставка в другую таблицу с полем IDENTITY. Тогда эта переменная будет показывать значение, относящееся к этой другой таблице. Для версий MS SQL ниже 2000 - единственная возможность узнать значение счетчика. Работает так: INSERT .... VALUES( ... ) SELECT @@IDENTITY /* Вернет значение для последней операции вставки */ 2. Для MS SQL 2000 существует более корректный способ - применение функции IDENT_CURRENT('table_name'), которая возвращает значение счетчика для указанной таблицы, что позволяет обойти проблему с триггером, описанную в п.1 ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 23.07.2002, 10:32:46 |
|
||
|
Помогите новичку (многие ко многим)
|
|||
|---|---|---|---|
|
#18+
Сапсибо! Можно уточнить на счет текущего сеанса. Т.е если я в пределах одной транзакции делаю Insert а за тем SELECT IDENT_CURRENT('table_name') в промежутке между этими командами возможна вставка записи другим клиентом? Не нужно блокировать таблицу? Если нужно то Как? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 23.07.2002, 10:50:39 |
|
||
|
Помогите новичку (многие ко многим)
|
|||
|---|---|---|---|
|
#18+
Вставка записи другим клиентом возможна. Однако это никак не отразится на значении, возвращаемом IDENT_CURRENT('table_name'). Для каждого нового соединения формируется отдельный счетчик, независимый от действий других соединений. Т.е. IDENT_CURRENT('table_name') будет возвращать последнее использованное значение именно в текущем соединении. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 23.07.2002, 11:04:10 |
|
||
|
Помогите новичку (многие ко многим)
|
|||
|---|---|---|---|
|
#18+
Спасибо! Пойняв! ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 23.07.2002, 11:12:58 |
|
||
|
Помогите новичку (многие ко многим)
|
|||
|---|---|---|---|
|
#18+
IDENT_CURRENT('table_name') как раз одна для всех сессий, поэтому применение её - источник потенциальных граблей. Для каждой сессии свои: @@IDENTITY и SCOPE_IDENTITY(). SCOPE_IDENTITY() более предпочтительно, так как вставка в триггере её не "портит". ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 23.07.2002, 12:05:20 |
|
||
|
Помогите новичку (многие ко многим)
|
|||
|---|---|---|---|
|
#18+
>AS76 А как сотрудник может быть во многих командировках. Мне казалось, что снала одна, потом другая и т.д. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 23.07.2002, 13:21:35 |
|
||
|
Помогите новичку (многие ко многим)
|
|||
|---|---|---|---|
|
#18+
Как вариант можно использовать отдельную процедуру, которая будет генерировать следующее значение. например, GET_NEXT_ID(@tableName varchar(32), ID float output) будет использоваться для получения следующего значения ID. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 23.07.2002, 13:48:28 |
|
||
|
Помогите новичку (многие ко многим)
|
|||
|---|---|---|---|
|
#18+
>Белов Владимир Понятно что одновременно нет. Это же описание отношений между таблицами и не более. Проверил IDENT_CURRENT('table_name'). Это как раз то что не нужно. С одной станции дал Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. А с другой сразу за этим тоже но с одной вставкой в табл. связи Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. И из 10000 записей первой операции одни строки вставились с одним IDENT_CURRENT ('TZ') а другие с другим. ГРАБЛИ! ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 23.07.2002, 13:53:03 |
|
||
|
Помогите новичку (многие ко многим)
|
|||
|---|---|---|---|
|
#18+
>AAron Как это решает проблему? Чем вызов процедуры отличается от вызова функции IDENT_CURRENT ('table_name')? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 23.07.2002, 14:10:46 |
|
||
|
Помогите новичку (многие ко многим)
|
|||
|---|---|---|---|
|
#18+
TO Dankov СПАСИБО ОГРОМНОЕ!!!!! SCOPE_IDENTITY() -- именно то что нужно! ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 23.07.2002, 14:51:57 |
|
||
|
Помогите новичку (многие ко многим)
|
|||
|---|---|---|---|
|
#18+
Наверно я перегрелся на нашей жаре. >1. Вставить запись в табл. Командировки я так понял за раз в ставляется только одна запись, и id - это счетчик а че в триггере на INSERT нельзя IF (@@ROWCOUNT=1) begin DECLARE @id int SELECT @id=id FROM INSERTED ........... end else print 'перегрев' ну и дальше различные манипуляции с @id ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 24.07.2002, 00:17:45 |
|
||
|
|

start [/forum/topic.php?fid=46&tid=1821613]: |
0ms |
get settings: |
7ms |
get forum list: |
15ms |
check forum access: |
3ms |
check topic access: |
3ms |
track hit: |
36ms |
get topic data: |
9ms |
get forum data: |
2ms |
get page messages: |
46ms |
get tp. blocked users: |
1ms |
| others: | 192ms |
| total: | 314ms |

| 0 / 0 |
