powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Microsoft SQL Server [игнор отключен] [закрыт для гостей] / Помогите новичку (многие ко многим)
12 сообщений из 12, страница 1 из 1
Помогите новичку (многие ко многим)
    #32038168
AS76
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Добрый день! Прошу помощи!
У меня MSSQL 2000.
Такя ситуация:
Есть две таблицы "сотрудники" и "командировки"
У каждой PK - это SMALLINT IDENTITY.
Каждый сотрудник может быть во многих командировках и в одной командировке может быть много сотрудников, т.е. связь "многие ко многим". Эту связь разрешаю созданием третьей таблицы "командировка-сотрудник" в которой два поля id сотрудника id командировки.
При записи информации о командировке мне необходимо выполнить следующие действия:
1. Вставить запись в табл. Командировки
2.Получить id этой записи
3. Вставить в таблицу связи столько записей сколько сотрудников едет в командировку(с id полученным в пункте 2)
Понятно что это все одна транзакция.
Такой вопрос:
Как мне гарантировать что во втором пункте я получу именно тот id который мне нужно, т.е. что в этот момент никто другой не вставит запись в таблицу командировки и я получу следующий(не верный id)?
Как это грамотно реализовать?
Простите если это все бред.
Спасибо.
...
Рейтинг: 0 / 0
Помогите новичку (многие ко многим)
    #32038171
Фотография Jimmy
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Для этого существует две возможности:
1. Использование системной переменной @@IDENTITY, которая возвращает последнее значение поля IDENTITY, в которое производилась вставка в текущем сеансе. Не гарантирует, что вернет именно то значение (относящееся к нужной таблице), которое ты ожидаешь получить, т.к. возможно, что существует триггер, в котором осуществляется вставка в другую таблицу с полем IDENTITY.
Тогда эта переменная будет показывать значение, относящееся к этой другой таблице.
Для версий MS SQL ниже 2000 - единственная возможность узнать значение счетчика.

Работает так:
INSERT .... VALUES( ... )
SELECT @@IDENTITY /* Вернет значение для последней операции вставки */

2. Для MS SQL 2000 существует более корректный способ - применение функции IDENT_CURRENT('table_name'), которая возвращает значение счетчика для указанной таблицы, что позволяет обойти проблему с триггером, описанную в п.1
...
Рейтинг: 0 / 0
Помогите новичку (многие ко многим)
    #32038176
AS76
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Сапсибо!
Можно уточнить на счет текущего сеанса.
Т.е если я в пределах одной транзакции
делаю Insert а за тем SELECT IDENT_CURRENT('table_name')
в промежутке между этими командами возможна вставка записи другим клиентом?
Не нужно блокировать таблицу?
Если нужно то Как?
...
Рейтинг: 0 / 0
Помогите новичку (многие ко многим)
    #32038178
Фотография ВладимирМ
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Вставка записи другим клиентом возможна. Однако это никак не отразится на значении, возвращаемом IDENT_CURRENT('table_name').

Для каждого нового соединения формируется отдельный счетчик, независимый от действий других соединений. Т.е. IDENT_CURRENT('table_name') будет возвращать последнее использованное значение именно в текущем соединении.
...
Рейтинг: 0 / 0
Помогите новичку (многие ко многим)
    #32038180
AS76
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Спасибо! Пойняв!
...
Рейтинг: 0 / 0
Помогите новичку (многие ко многим)
    #32038197
Фотография ziktuw
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
IDENT_CURRENT('table_name') как раз одна для всех сессий, поэтому применение её - источник потенциальных граблей.

Для каждой сессии свои: @@IDENTITY и SCOPE_IDENTITY(). SCOPE_IDENTITY() более предпочтительно, так как вставка в триггере её не "портит".
...
Рейтинг: 0 / 0
Помогите новичку (многие ко многим)
    #32038225
Фотография Белов Владимир
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
>AS76
А как сотрудник может быть во многих командировках.
Мне казалось, что снала одна, потом другая и т.д.
...
Рейтинг: 0 / 0
Помогите новичку (многие ко многим)
    #32038242
AAron
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Как вариант можно использовать отдельную процедуру, которая будет генерировать следующее значение.
например, GET_NEXT_ID(@tableName varchar(32), ID float output) будет использоваться для получения следующего значения ID.
...
Рейтинг: 0 / 0
Помогите новичку (многие ко многим)
    #32038244
AS76
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
>Белов Владимир
Понятно что одновременно нет.
Это же описание отношений между таблицами и не более.
Проверил IDENT_CURRENT('table_name').
Это как раз то что не нужно.
С одной станции дал

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
Declare @schet SMALLINT
SELECT @schet= 1 
insert into TZ (....)
   values
  (...)
   
WHILE @schet< 10000 
BEGIN   
   insert into TZ_USERS (KOD_USER, KOD_TZ)
   values
  ( 11 ,IDENT_CURRENT ('TZ'))
   SELECT @schet=@schet+ 1  
END


А с другой сразу за этим тоже но с одной вставкой в табл. связи
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
Declare @schet SMALLINT
SELECT @schet= 1 
insert into TZ (....)
   values
  (...)

   insert into TZ_USERS (KOD_USER, KOD_TZ)
   values
  ( 12 ,IDENT_CURRENT ('TZ'))


И из 10000 записей первой операции одни строки вставились с одним IDENT_CURRENT ('TZ') а другие с другим.
ГРАБЛИ!
...
Рейтинг: 0 / 0
Помогите новичку (многие ко многим)
    #32038248
AS76
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
>AAron

Как это решает проблему? Чем вызов процедуры отличается от вызова функции IDENT_CURRENT ('table_name')?
...
Рейтинг: 0 / 0
Помогите новичку (многие ко многим)
    #32038263
AS76
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
TO Dankov

СПАСИБО ОГРОМНОЕ!!!!!
SCOPE_IDENTITY() -- именно то что нужно!
...
Рейтинг: 0 / 0
Помогите новичку (многие ко многим)
    #32038389
Smile
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Наверно я перегрелся на нашей жаре.
>1. Вставить запись в табл. Командировки

я так понял за раз в ставляется только одна запись, и id - это счетчик

а че в триггере на INSERT нельзя

IF (@@ROWCOUNT=1)
begin
DECLARE @id int
SELECT @id=id FROM INSERTED
...........
end
else print 'перегрев'

ну и дальше различные манипуляции с @id
...
Рейтинг: 0 / 0
12 сообщений из 12, страница 1 из 1
Форумы / Microsoft SQL Server [игнор отключен] [закрыт для гостей] / Помогите новичку (многие ко многим)
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]