Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Microsoft SQL Server Новый топик    Ответить
Топик располагается на нескольких страницах: [1] 2   вперед  Ctrl      все
 Получение диапазона ключей для вставленных значений  [new]
vma_mnt
Member

Откуда: Новокузнецк
Сообщений: 602
Есть две таблицы, родительская и подчиненная. В родительскую вставляются строки. При этом надо получить диапазон вставленных ключей и вставить эти ключи в подчиненную таблицу.

Я думаю получить перед началом вставки последнее значение ключа, а после вставки через @@SCOPE_IDENTITY.

А если после получения последнего значения ключа другой пользователь вставит значения, я получу неправильный диапазон.

Как можно реализовать следующие действия:
заблокировать таблицу,
получить последнее значение ключа,
вставить данные
получить @@SCOPE_IDENTITY
разблокировать таблицу
29 мар 05, 19:47    [1424568]     Ответить | Цитировать Сообщить модератору
 Re: Получение диапазона ключей для вставленных значений  [new]
Breakneck
Member

Откуда: Kiev
Сообщений: 2454
Транзакция с уровнем изоляции SERIALIZABLE
29 мар 05, 19:50    [1424575]     Ответить | Цитировать Сообщить модератору
 Re: Получение диапазона ключей для вставленных значений  [new]
Alex.Czech
Guest
Или
INSERT INTO table WITH (HOLDLOCK, TABLOCK), что в принципе то же самое, но для одной инструкции :)
29 мар 05, 23:28    [1424860]     Ответить | Цитировать Сообщить модератору
 Re: Получение диапазона ключей для вставленных значений  [new]
vma_mnt
Member

Откуда: Новокузнецк
Сообщений: 602
Alex.Czech
Или
INSERT INTO table WITH (HOLDLOCK, TABLOCK), что в принципе то же самое, но для одной инструкции :)


Это понятно. Вопрос в другом. Как гарантированно до начала вставки получить последнее значение ключа.

То есть, получаю последнее значение ключа. После этого другой пользователь вставляет значения. После чего я вставляю с блокировкой таблицы. В результате я получаю диапазон, включающий чужие значения. Вот этого хочется как-то избежать.

Если я сделаю следующее

SET TRANSACTION ISOLATION LEVEL  SERIALIZABLE 
begin tran
select @FirstIdentityValue = max(PrimaryKey) from Table
insert into Table ....
set @LastIdentityValue = @@SCOPE_IDENTITY
commit tran

то может ли другой пользователь вклиниться между командами
select @FirstIdentityValue и
insert into Table
30 мар 05, 04:25    [1424970]     Ответить | Цитировать Сообщить модератору
 Re: Получение диапазона ключей для вставленных значений  [new]
tpg
Member

Откуда: Novosibirsk
Сообщений: 23902
vma_mnt
может ли другой пользователь вклиниться между командами
select @FirstIdentityValue и
insert into Table
Может то он может, но вот SCOPE_IDENTITY() вернет всегда последнее значение колонки идентити, вставленное в своей "области" - на то она и SCOPE! И ни каких движений с изоляционным уровнем транзакции не требуется.
30 мар 05, 06:42    [1424998]     Ответить | Цитировать Сообщить модератору
 Re: Получение диапазона ключей для вставленных значений  [new]
aleks2
Guest
Правильно так

insert into Table ....
set @FirstIdentityValue = SCOPE_IDENTITY()-@@rowcount
set @LastIdentityValue = SCOPE_IDENTITY()
30 мар 05, 07:00    [1425009]     Ответить | Цитировать Сообщить модератору
 Re: Получение диапазона ключей для вставленных значений  [new]
vma_mnt
Member

Откуда: Новокузнецк
Сообщений: 602
tpg
vma_mnt
может ли другой пользователь вклиниться между командами
select @FirstIdentityValue и
insert into Table
Может то он может, но вот SCOPE_IDENTITY() вернет всегда последнее значение колонки идентити, вставленное в своей "области" - на то она и SCOPE! И ни каких движений с изоляционным уровнем транзакции не требуется.


Так вот об этом и речь. Между @FirstIdentityValue и SCOPE_IDENTITY() будут находиться чужие значения.
30 мар 05, 08:14    [1425065]     Ответить | Цитировать Сообщить модератору
 Re: Получение диапазона ключей для вставленных значений  [new]
aleks2
Guest
vma_mnt
tpg
vma_mnt
может ли другой пользователь вклиниться между командами
select @FirstIdentityValue и
insert into Table
Может то он может, но вот SCOPE_IDENTITY() вернет всегда последнее значение колонки идентити, вставленное в своей "области" - на то она и SCOPE! И ни каких движений с изоляционным уровнем транзакции не требуется.


Так вот об этом и речь. Между @FirstIdentityValue и SCOPE_IDENTITY() будут находиться чужие значения.


Тэбэ, дарагой, русскими словами объясняют:
1) SCOPE_IDENTITY() - содержит последний IDENTITY, вставленный в текущем бэтче (процедуре). Никакие другие вставки, другие пользователи и т.п. и т.д. на него не влияют.
2) INSERT выполняется в транзакции => все вставленные IDENTITY образуют непрерывный диапазон и SCOPE_IDENTITY() равен последнему из них. Никто не может в него (в диапазон IDENTITY одного INSERT-а) вклиниться.
------------------------------
не парься...
30 мар 05, 08:51    [1425125]     Ответить | Цитировать Сообщить модератору
 Re: Получение диапазона ключей для вставленных значений  [new]
VladRUS.ca
Member

Откуда: Toronto
Сообщений: 1172
vma_mnt
Есть две таблицы, родительская и подчиненная. В родительскую вставляются строки. При этом надо получить диапазон вставленных ключей и вставить эти ключи в подчиненную таблицу.
Я использую при таких вставках Второй уникальный ключ родителя:

create table tParent(ParentID int identity primary key, ParentAK varchar(10) UNIQUE, Info varchar(20) )
go
create table tChild(ChildID int identity primary key, ParentID int, Info varchar(20))
go

declare @tParent table(ParentAK varchar(10), Info varchar(20))
insert into @tParent(ParentAK, Info)
    select 'AAA', 'Parent AAA' union
    select 'BBB', 'Parent BBB' union
    select 'CCC', 'Parent CCC'

declare @tChild table(ParentAK varchar(10), Info varchar(20))
insert into @tChild(ParentAK, Info)
    select 'AAA', 'Child AAA Line 1' union
    select 'AAA', 'Child AAA Line 2' union
    select 'AAA', 'Child AAA Line 3' union
    select 'BBB', 'Child BBB Line 1' union
    select 'BBB', 'Child BBB Line 2' union
    select 'CCC', 'Child CCC Line 1' union
    select 'CCC', 'Child CCC Line 2'

insert into tParent(ParentAK, Info)
    select ParentAK, Info 
    from @tParent

insert into tChild(ParentID, Info)
    select t2.ParentID, t1.Info
    from @tChild t1 inner join tParent t2 on
        t1.ParentAK = t2.ParentAK

select * from tParent
select * from tChild
30 мар 05, 09:12    [1425175]     Ответить | Цитировать Сообщить модератору
 Re: Получение диапазона ключей для вставленных значений  [new]
unicode
Member

Откуда:
Сообщений: 810
IDENT_CURRENT
Returns the last identity value generated for a specified table in any session and any scope. 
30 мар 05, 09:21    [1425190]     Ответить | Цитировать Сообщить модератору
 Re: Получение диапазона ключей для вставленных значений  [new]
tpg
Member

Откуда: Novosibirsk
Сообщений: 23902
unicode
IDENT_CURRENT
Returns the last identity value generated for a specified table in any session and any scope. 
А это тут автору зачем?
30 мар 05, 09:38    [1425230]     Ответить | Цитировать Сообщить модератору
 Re: Получение диапазона ключей для вставленных значений  [new]
WiRuc
Member

Откуда: Воронеж
Сообщений: 1280
aleks2
vma_mnt
tpg
vma_mnt
может ли другой пользователь вклиниться между командами
select @FirstIdentityValue и
insert into Table
Может то он может, но вот SCOPE_IDENTITY() вернет всегда последнее значение колонки идентити, вставленное в своей "области" - на то она и SCOPE! И ни каких движений с изоляционным уровнем транзакции не требуется.


Так вот об этом и речь. Между @FirstIdentityValue и SCOPE_IDENTITY() будут находиться чужие значения.


Тэбэ, дарагой, русскими словами объясняют:
1) SCOPE_IDENTITY() - содержит последний IDENTITY, вставленный в текущем бэтче (процедуре). Никакие другие вставки, другие пользователи и т.п. и т.д. на него не влияют.
2) INSERT выполняется в транзакции => все вставленные IDENTITY образуют непрерывный диапазон и SCOPE_IDENTITY() равен последнему из них. Никто не может в него (в диапазон IDENTITY одного INSERT-а) вклиниться.
------------------------------
не парься...


Да ну:)
С чего вы взяли, что INSERT образует непрерывную последовательность? Если бы это было так, то о никакой конкуретной вставке речи бы не шло, т.е. производительность была бы ужасающей. То что, INSERT выполняется в транзакции - верно, то что другой INSERT не сможет вставить в этот момент запись - неверно.
30 мар 05, 09:51    [1425272]     Ответить | Цитировать Сообщить модератору
 Re: Получение диапазона ключей для вставленных значений  [new]
Alex.Czech
Guest
Можно в триггере сливать содержимое inserted в какую-то третью таблицу (где во избежание путаницы юзеров например будет поле spid, по которому вы сможете отобрать "свои" записи). Другой вопрос, кто и когда будет эту таблицу чистить
30 мар 05, 10:04    [1425321]     Ответить | Цитировать Сообщить модератору
 Re: Получение диапазона ключей для вставленных значений  [new]
Smirnov Anton
Member

Откуда: Н.Новгород
Сообщений: 3220
WiRuc

Да ну:)
С чего вы взяли, что INSERT образует непрерывную последовательность? Если бы это было так, то о никакой конкуретной вставке речи бы не шло, т.е. производительность была бы ужасающей. То что, INSERT выполняется в транзакции - верно, то что другой INSERT не сможет вставить в этот момент запись - неверно.

те вы считаете, что пока в одном батче идёт большой
insert into ... select
в дрогом можно по шурику
insert into ... values() - и это вставится в середину первого набора?
30 мар 05, 10:08    [1425326]     Ответить | Цитировать Сообщить модератору
 Re: Получение диапазона ключей для вставленных значений  [new]
WiRuc
Member

Откуда: Воронеж
Сообщений: 1280
Еще добавлю, что даже уровень изоляции SERIALIZABLE без предварительной вычитки не обечпечивает гарантии того, что не будет производится вставок в таблицу.

Так что вариант
vma_mnt

SET TRANSACTION ISOLATION LEVEL  SERIALIZABLE 
begin tran
select @FirstIdentityValue = max(PrimaryKey) from Table
insert into Table ....
set @LastIdentityValue = @@SCOPE_IDENTITY
commit tran

является единственно правильным.
30 мар 05, 10:13    [1425345]     Ответить | Цитировать Сообщить модератору
 Re: Получение диапазона ключей для вставленных значений  [new]
aleks2
Guest
WiRuc
aleks2
vma_mnt
tpg
vma_mnt
может ли другой пользователь вклиниться между командами
select @FirstIdentityValue и
insert into Table
Может то он может, но вот SCOPE_IDENTITY() вернет всегда последнее значение колонки идентити, вставленное в своей "области" - на то она и SCOPE! И ни каких движений с изоляционным уровнем транзакции не требуется.


Так вот об этом и речь. Между @FirstIdentityValue и SCOPE_IDENTITY() будут находиться чужие значения.


Тэбэ, дарагой, русскими словами объясняют:
1) SCOPE_IDENTITY() - содержит последний IDENTITY, вставленный в текущем бэтче (процедуре). Никакие другие вставки, другие пользователи и т.п. и т.д. на него не влияют.
2) INSERT выполняется в транзакции => все вставленные IDENTITY образуют непрерывный диапазон и SCOPE_IDENTITY() равен последнему из них. Никто не может в него (в диапазон IDENTITY одного INSERT-а) вклиниться.
------------------------------
не парься...


Да ну:)
С чего вы взяли, что INSERT образует непрерывную последовательность? Если бы это было так, то о никакой конкуретной вставке речи бы не шло, т.е. производительность была бы ужасающей. То что, INSERT выполняется в транзакции - верно, то что другой INSERT не сможет вставить в этот момент запись - неверно.


А никто не говорит: "другой INSERT не сможет вставить в этот момент запись".
Сказано: другой INSERT сможет вставить dэтот момент запись, НО в другой диапазон IDENTITY.
30 мар 05, 10:14    [1425351]     Ответить | Цитировать Сообщить модератору
 Re: Получение диапазона ключей для вставленных значений  [new]
WiRuc
Member

Откуда: Воронеж
Сообщений: 1280
Smirnov Anton
WiRuc

Да ну:)
С чего вы взяли, что INSERT образует непрерывную последовательность? Если бы это было так, то о никакой конкуретной вставке речи бы не шло, т.е. производительность была бы ужасающей. То что, INSERT выполняется в транзакции - верно, то что другой INSERT не сможет вставить в этот момент запись - неверно.

те вы считаете, что пока в одном батче идёт большой
insert into ... select
в дрогом можно по шурику
insert into ... values() - и это вставится в середину первого набора?


Однозначно. В этом и заключаетя конкурентная работа с таблицей.
30 мар 05, 10:15    [1425359]     Ответить | Цитировать Сообщить модератору
 Re: Получение диапазона ключей для вставленных значений  [new]
WiRuc
Member

Откуда: Воронеж
Сообщений: 1280
aleks2
WiRuc
aleks2
vma_mnt
tpg
vma_mnt
может ли другой пользователь вклиниться между командами
select @FirstIdentityValue и
insert into Table
Может то он может, но вот SCOPE_IDENTITY() вернет всегда последнее значение колонки идентити, вставленное в своей "области" - на то она и SCOPE! И ни каких движений с изоляционным уровнем транзакции не требуется.


Так вот об этом и речь. Между @FirstIdentityValue и SCOPE_IDENTITY() будут находиться чужие значения.


Тэбэ, дарагой, русскими словами объясняют:
1) SCOPE_IDENTITY() - содержит последний IDENTITY, вставленный в текущем бэтче (процедуре). Никакие другие вставки, другие пользователи и т.п. и т.д. на него не влияют.
2) INSERT выполняется в транзакции => все вставленные IDENTITY образуют непрерывный диапазон и SCOPE_IDENTITY() равен последнему из них. Никто не может в него (в диапазон IDENTITY одного INSERT-а) вклиниться.
------------------------------
не парься...


Да ну:)
С чего вы взяли, что INSERT образует непрерывную последовательность? Если бы это было так, то о никакой конкуретной вставке речи бы не шло, т.е. производительность была бы ужасающей. То что, INSERT выполняется в транзакции - верно, то что другой INSERT не сможет вставить в этот момент запись - неверно.


А никто не говорит: "другой INSERT не сможет вставить в этот момент запись".
Сказано: другой INSERT сможет вставить dэтот момент запись, НО в другой диапазон IDENTITY.


Что вы тогда понимаете под другим диапозоном? Непрерывная последовательность ID для первого инсерта будет разорвана и где тут второй диапозон?
30 мар 05, 10:17    [1425366]     Ответить | Цитировать Сообщить модератору
 Re: Получение диапазона ключей для вставленных значений  [new]
aleks2
Guest
WiRuc

Что вы тогда понимаете под другим диапозоном? Непрерывная последовательность ID для первого инсерта будет разорвана и где тут второй диапозон?


Экий вы, батенька, непонятливый...
Пусть параллельно идут ДВА инсерта, пусть в момент начала инсертов IDENTITY=1, пусть 1-инсерт начался на мгновение раньше, пусть оба инсерта вставляют по 10 записей.
Тогда 1-инсерт получит диапазон ID 1-10 и вставит записи с этим IDENTITY, а 2-инсерт получит диапазон ID 11-20 и вставит записи с этим IDENTITY.
--------------
могете проверить...
30 мар 05, 10:23    [1425395]     Ответить | Цитировать Сообщить модератору
 Re: Получение диапазона ключей для вставленных значений  [new]
WiRuc
Member

Откуда: Воронеж
Сообщений: 1280
aleks2
WiRuc

Что вы тогда понимаете под другим диапозоном? Непрерывная последовательность ID для первого инсерта будет разорвана и где тут второй диапозон?


Экий вы, батенька, непонятливый...
Пусть параллельно идут ДВА инсерта, пусть в момент начала инсертов IDENTITY=1, пусть 1-инсерт начался на мгновение раньше, пусть оба инсерта вставляют по 10 записей.
Тогда 1-инсерт получит диапазон ID 1-10 и вставит записи с этим IDENTITY, а 2-инсерт получит диапазон ID 11-20 и вставит записи с этим IDENTITY.
--------------
могете проверить...


Не будет такого. Записи будут вставляться в перемешку.
Можете проверить...
30 мар 05, 10:26    [1425410]     Ответить | Цитировать Сообщить модератору
 Re: Получение диапазона ключей для вставленных значений  [new]
tpg
Member

Откуда: Novosibirsk
Сообщений: 23902
2 WiRuc
Ссылочку на доку или цитату из инсайд можно увидеть о правоте утверждаемого?
30 мар 05, 10:40    [1425475]     Ответить | Цитировать Сообщить модератору
 Re: Получение диапазона ключей для вставленных значений  [new]
Smirnov Anton
Member

Откуда: Н.Новгород
Сообщений: 3220
проверил...
действительно WiRuc прав
30 мар 05, 10:42    [1425483]     Ответить | Цитировать Сообщить модератору
 Re: Получение диапазона ключей для вставленных значений  [new]
WiRuc
Member

Откуда: Воронеж
Сообщений: 1280
tpg
2 WiRuc
Ссылочку на доку или цитату из инсайд можно увидеть о правоте утверждаемого?


Да это же основа транзакций, как в теории, так и на практике.
Нигде не говориться о том, что уровень SERIALIZABLE не дает производить параллельные операции над таблицей. Везде говориться о СНИЖЕНИИ конкурентности работы с таблицей. Этот уровень обеспечивает целостность данных, ЗАТРОНУТЫХ транзакцией или данных, которые МОГЛИ БЫТЬ ЗАТРОНУТЫ транзакцией. Это говорит о том, что если я не произведу вычетку по всей таблице (или интересующему меня диапазону), то это автоматически разрешает другой транзакции вставлять записи, т.к. они не нарушают целостность первой транзакции.
30 мар 05, 10:54    [1425538]     Ответить | Цитировать Сообщить модератору
 Re: Получение диапазона ключей для вставленных значений  [new]
tpg
Member

Откуда: Novosibirsk
Сообщений: 23902
Smirnov Anton
проверил...
действительно WiRuc прав
Скрипт теста можно привести?
30 мар 05, 11:07    [1425580]     Ответить | Цитировать Сообщить модератору
 Re: Получение диапазона ключей для вставленных значений  [new]
баззззлайтер
Guest
5 коп.:
вот так, вроде, тоже exclusive lock должен получится?
begin tran
select @FirstIdentityValue = max(PrimaryKey) from Table (UPDLOCK, HOLDLOCK)
30 мар 05, 11:13    [1425603]     Ответить | Цитировать Сообщить модератору
Топик располагается на нескольких страницах: [1] 2   вперед  Ctrl      все
Все форумы / Microsoft SQL Server Ответить