Теперь мне нужно эти значения без таблички генерить
Беспокоит мысль: если два клиента одновременно вызовут процедуру/функцию генерации этого значения, то она (процедура/ф-ция) вернёт одинаковые значения
Мне бы этого не хотелось
Подскажите
ps. что-то наподобие ораклийного сиквенса должно получиться
Здравствуйте, _d_m_, Вы писали:
___>Здравствуйте, Andro1900, Вы писали:
A>>Табличка в ней PK int identity(1,1)
A>>Теперь мне нужно эти значения без таблички генерить
___>Это все равно делается через вспомогательную таблицу.
A>>ps. что-то наподобие ораклийного сиквенса должно получиться
___>А вот через таблицу, сиквенса не получится — блокировки в транзакциях неизбежны. Тогда остаются только внешние средства типа CLR-процедур.
Чего-то я не понимаю, то вы пишите это делается через вспомогательную таблицу, то "через таблицу, сиквенса не получится"
Здравствуйте, Andro1900, Вы писали:
A>Чего-то я не понимаю, то вы пишите это делается через вспомогательную таблицу, то "через таблицу, сиквенса не получится"
Здравствуйте, Andro1900, Вы писали:
A>Табличка в ней PK int identity(1,1)
A>Теперь мне нужно эти значения без таблички генерить A>Беспокоит мысль: если два клиента одновременно вызовут процедуру/функцию генерации этого значения, то она (процедура/ф-ция) вернёт одинаковые значения A>Мне бы этого не хотелось A>ps. что-то наподобие ораклийного сиквенса должно получиться
d_m правльно говорит: не получится сиквенса. Сиквенс и identity штуки нетранзакционные. То есть транзакция при откате не откатывает их состояние назад. Это дает возможность не блокировать их, то есть получил значение — отходи, следующий.
С таблицей все иначе. Если транзакция что-то в ней поменяла, то никто другой не может ни прочитать ни поменять данные, поскольку стоит блокировка (ну, для оракла может и не совсем так, но состояние сиквенса точно не откатывается). Если это не беспокоит, и нужно просто получать последовательные значения, то делается так:
1) создается табличка типа KeyTable(LastId int not null)
2) пишется процедура с текстом типа:
proc GetKey @id int out
as
update KeyTable set @id = LastId + 1, LastId = LastId + 1
Здравствуйте, Andro1900, Вы писали:
A>Табличка в ней PK int identity(1,1)
A>Теперь мне нужно эти значения без таблички генерить A>Беспокоит мысль: если два клиента одновременно вызовут процедуру/функцию генерации этого значения, то она (процедура/ф-ция) вернёт одинаковые значения A>Мне бы этого не хотелось
A>Подскажите
A>ps. что-то наподобие ораклийного сиквенса должно получиться
Как-то так
CREATE TABLE Sequence( Id int identity( 1, 1 ) NOT NULL )
GO
CREATE PROCEDURE Sequence_Next
AS
BEGIN
SET NOCOUNT ON
BEGIN TRAN
INSERT INTO Sequence DEFAULT VALUES
ROLLBACK
RETURN @@IDENTITY
END
GO
DECLARE @id int
WHILE 1=1
BEGIN
EXEC @id = Sequence_Next
PRINT @id
END
Здравствуйте, Козьма Прутков, Вы писали:
КП> Сиквенс и identity штуки нетранзакционные.
Чуть поправлю: они штуки "вне текущей транзакции". В Оракле есть понятие автономной транзакции, и для сиквенса используется именно оно (и с помощью этого понятия в принципе можно написать "свой аналог сиквенса", хотя менее эффективный из-за затруднительности кэширования).
В MSSQL аналог идентити наверное разумнее писать внешней процедурой, хотя полагаю, можно сделать и на T-SQL, используя грязное чтение. Логика примерно следующая:
— делаем таблицу "значений"
— через sp_lock разруливаем одновременный доступ
— если она пуста, вставляем в нее N очередных значений
— забираем очередную значение, читая грязным чтением, и удаляем запись.
Бонусом получаем любимое бухгалтерами отсутствие дырок в нумерации