Индексы и MS SQL Server 2000
От: .smoke Россия  
Дата: 13.10.02 21:08
Оценка:
Пишу Web Service, с MS SQL Serverom вообще не работал
Вот наткнулся на такую вещь, есть табличка, мне нужно в нее вставить строку и получить идентификатор (уникальное поле)
под которым она вставилась, чтобы в последующих функциях работать с это строкой. Посоветуйте, как это лусше сделать?
Re: Индексы и MS SQL Server 2000
От: .smoke Россия  
Дата: 13.10.02 21:29
Оценка:
Я прошу меня извенить, здесь клнечнл уже много раз это обсуждали, но просмотрев треды у меня все-таки остался вопрос
Если я сделаю вот так

INSERT INTO .... VALUES (....) SELECT @@IDENTITY;


Возможна ли такая ситуация, что между INSERT и SELECT кто-нибудь другой втисниться и успеет сделать INSERT?
Re[2]: Индексы и MS SQL Server 2000
От: Lloyd Россия  
Дата: 14.10.02 05:07
Оценка:
Здравствуйте .smoke, Вы писали:

S>Я прошу меня извенить, здесь клнечнл уже много раз это обсуждали, но просмотрев треды у меня все-таки остался вопрос

S>Если я сделаю вот так

S>
S>INSERT INTO .... VALUES (....) SELECT @@IDENTITY;
S>


S>Возможна ли такая ситуация, что между INSERT и SELECT кто-нибудь другой втисниться и успеет сделать INSERT?


Нет. (с)
(Свежее дыхание облегчает понимание)
Re[3]: Индексы и MS SQL Server 2000
От: Алекс Россия http://wise-orm.com
Дата: 14.10.02 10:23
Оценка: 9 (2) -1
Здравствуйте Lloyd, Вы писали:

L>Здравствуйте .smoke, Вы писали:


[]

L>Нет. (с)


Это почему? Наоборот! Да'с!

Аргументирую. Если сервер работает в режиме автоматических транзакций, то
MSDN:
individual Transact-SQL statement is committed automatically if it is successful and rolled back automatically if it generates an error.

В таком случае между insert'ом и последующим select'ом может проскочить другая транзакция. Результат будет не верный. Для предотвращения этого необходимо непосредственно указать принадлежность двух инструкций одной транзакции.
При чем, если тупо написать
begin tran
insert into dmd values(1291,4575)
select @@IDENTITY
commit

то это не особо поможет. Так как после insert пользователю (по умолчанию) запрещается только читать данные. Необходимо явно указать вид блокировки.
begin tran
insert into dmd with (tablock) values(1291,4575)
select @@IDENTITY
commit
Re[2]: Индексы и MS SQL Server 2000
От: Admiral Украина  
Дата: 14.10.02 11:58
Оценка:
Здравствуйте .smoke, Вы писали:

S>Если я сделаю вот так

S>
S>INSERT INTO .... VALUES (....) SELECT @@IDENTITY;
S>

S>Возможна ли такая ситуация, что между INSERT и SELECT кто-нибудь другой втисниться и успеет сделать INSERT?

Да. Алекс объяснил — почему. Но @@IDENTITY ты получишь правильный (т.е. ID строки, которую добавил ты, а не кто-то позже).
Re[3]: Индексы и MS SQL Server 2000
От: Алекс Россия http://wise-orm.com
Дата: 14.10.02 12:21
Оценка:
Здравствуйте Admiral, Вы писали:

A>Здравствуйте .smoke, Вы писали:


хъ

A>Да. Алекс объяснил — почему. Но @@IDENTITY ты получишь правильный (т.е. ID строки, которую добавил ты, а не кто-то позже).


Да, ты прав. Эта функция возвращает

MSDN:
last identity value generated in any table in the current session.
Re[4]: Индексы и MS SQL Server 2000
От: Lloyd Россия  
Дата: 14.10.02 12:56
Оценка:
Здравствуйте Алекс, Вы писали:

Мог тогда бы уж и про триггеры рассказать. Что они тоже могуть ситуацию подпортить
Re[4]: Индексы и MS SQL Server 2000
От: kmorozov  
Дата: 14.10.02 13:20
Оценка:
Здравствуйте Алекс, Вы писали:

А>last identity value generated in any table in the current session.


Или можно использовать
IDENT_CURRENT('table_name') -Returns the last identity value generated for a specified table in any session and any scope.
Re[4]: Что ж ты людей-то путаешь!....
От: Merle Австрия http://rsdn.ru
Дата: 15.10.02 06:15
Оценка: 36 (1)
Здравствуйте Алекс, Вы писали:

А>individual Transact-SQL statement is committed automatically if it is successful and rolled back automatically if it generates an error.


А>В таком случае между insert'ом и последующим select'ом может проскочить другая транзакция. Результат будет не верный. Для предотвращения этого необходимо непосредственно указать принадлежность двух инструкций одной транзакции.



Другая транзакция конечно может влезть, но на @@IDENTITY это не повлияет никак, посему все извращения с транзакциями и блокировками можно опустить ибо @@IDENTITY возвращает последнее значение столбца с IDENTITY в пределах текущей сессии.
Единственный вариант когда @@IDENTITY может вернуть неверное значение это если на таблице висит триггер на INSERT, который тоже что-то, кому-то, куда-то вставляет, в этом случае @@IDENTITY возвращает значение этого что-то, где-то, кем-то, но опять же строго в пределах текущей сессии.
Но так у них на хитрую задницу есть свой хрен с винтом, то у нас на их хрен с винтом есть своя ж@па с лабиринтом, в виде SCOPE_IDENTITY() который кладет афигенский болт на все триггеры на свете..

@@IDENTITY and SCOPE_IDENTITY will return the last identity value generated in any table
in the current session. However, SCOPE_IDENTITY returns the value only within the current
scope

A scope is a module -- a stored procedure, trigger, function, or batch. Thus, two
statements are in the same scope if they are in the same stored procedure, function, or
batch.
Мы уже победили, просто это еще не так заметно...
Re[5]: Вообще в FAQ пора и вообще FAQ пора ;) ...
От: Merle Австрия http://rsdn.ru
Дата: 15.10.02 06:50
Оценка:
И сам FAQ уже назрел и этот вопрос чуть ли не на первое место в этом FAQ'е....
Мы уже победили, просто это еще не так заметно...
Re[5]: Что ж ты людей-то путаешь!....
От: Алекс Россия http://wise-orm.com
Дата: 15.10.02 08:11
Оценка:
Здравствуйте Merle, Вы писали:

M>Здравствуйте Алекс, Вы писали:


А>>individual Transact-SQL statement is committed automatically if it is successful and rolled back automatically if it generates an error.


А>>В таком случае между insert'ом и последующим select'ом может проскочить другая транзакция. Результат будет не верный. Для предотвращения этого необходимо непосредственно указать принадлежность двух инструкций одной транзакции.


M>

M>Другая транзакция конечно может влезть, но на @@IDENTITY это не повлияет никак, посему все извращения с транзакциями и блокировками можно опустить ибо @@IDENTITY возвращает последнее значение столбца с IDENTITY в пределах текущей сессии.

[]

Ну забыл, и че! Зачем нулями-то разбрасываться! И же исправился (потом), к тому же этих нулей у меня и так много.

Если обощить, то нужно всегда думать о подобных вещах. Представть вместо SELECT @@IDENTITY выплнялся бы другой запрос из другой таблы, которая бы была связана с нашей. Могли бы возникнуть проблемы.

И сам FAQ уже назрел и этот вопрос чуть ли не на первое место в этом FAQ'е....

Про @@IDENTITY? Лучше бы про блокировки написал!
Re[6]: Что ж ты людей-то путаешь!....
От: Merle Австрия http://rsdn.ru
Дата: 15.10.02 09:09
Оценка:
Здравствуйте Алекс, Вы писали:


А>Ну забыл, и че! Зачем нулями-то разбрасываться! И же исправился (потом), к тому же этих нулей у меня и так много.


Ну, тем более, нулем больше — нулем меньше...
Вот уж девять баллов, ты точно не за что получил, так что это я чтобы справедливость хоть отчасти восторжествовала...


А>Если обощить, то нужно всегда думать о подобных вещах. Представть вместо SELECT @@IDENTITY выплнялся бы другой запрос из другой таблы, которая бы была связана с нашей. Могли бы возникнуть проблемы.

Ага, давай тогда вообще сделаем одну большую SERIALIZABLE транзакцию и всю работу с базой в эту транзакцию запихнем, точно никаких проблемм не будет.
А думать вообще никогда не вредно...


А>И сам FAQ уже назрел и этот вопрос чуть ли не на первое место в этом FAQ'е....


А>Про @@IDENTITY? Лучше бы про блокировки написал!

Да запросто... К тому же Sinclair это давно сделал, очень все доходчиво объяснил, насколько я помню.
Мы уже победили, просто это еще не так заметно...
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.