Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Microsoft SQL Server Новый топик    Ответить
 Вернуть @@IDENTITY дя типа uniqueidentifier  [new]
Naile
Member

Откуда: Latvija
Сообщений: 145
Id для каждой записи имеет тип uniqueidentifier

Пытаюсь получить значение Id для последнего добавленного элемента :

declare @AccountId uniqueidentifier
insert into Account (Name, Code) values ('my_name', 'my_code')
SET @AccountId = @@IDENTITY

И получаю ошибку :
Operand type clash: numeric is incompatible with uniqueidentifier

вариант
SET @AccountId = CONVERT(uniqueidentifier, @@IDENTITY)

дает
Explicit conversion from data type numeric to uniqueidentifier is not allowed.

Как мне получить Id в данном случае?
2 июл 13, 18:42    [14512561]     Ответить | Цитировать Сообщить модератору
 Re: Вернуть @@IDENTITY дя типа uniqueidentifier  [new]
Minamoto
Member

Откуда: Москва
Сообщений: 1162
Naile, никак.
declare @AccountId uniqueidentifier
set @AccountId = NEWID()
insert into Account (AccountID, Name, Code) values (@CoountID, 'my_name', 'my_code')
2 июл 13, 18:46    [14512570]     Ответить | Цитировать Сообщить модератору
 Re: Вернуть @@IDENTITY дя типа uniqueidentifier  [new]
Minamoto
Member

Откуда: Москва
Сообщений: 1162
Ошибся в названии переменной.
declare @AccountId uniqueidentifier
set @AccountId = NEWID()
insert into Account (AccountID, Name, Code) values (@AccountId, 'my_name', 'my_code')
2 июл 13, 18:47    [14512579]     Ответить | Цитировать Сообщить модератору
 Re: Вернуть @@IDENTITY дя типа uniqueidentifier  [new]
Naile
Member

Откуда: Latvija
Сообщений: 145
Minamoto,

Спасибо!
2 июл 13, 18:48    [14512580]     Ответить | Цитировать Сообщить модератору
 Re: Вернуть @@IDENTITY дя типа uniqueidentifier  [new]
aleks2
Guest
Minamoto
Naile, никак.
declare @AccountId uniqueidentifier
set @AccountId = NEWID()
insert into Account (AccountID, Name, Code) values (@CoountID, 'my_name', 'my_code')


Чо уж так-то безысходно?

declare @IDs table(ID uniqueidentifier);

insert into Account ( Name, Code) 
output inserted.AccountID into @IDs
values ( 'my_name', 'my_code')
2 июл 13, 18:51    [14512589]     Ответить | Цитировать Сообщить модератору
 Re: Вернуть @@IDENTITY дя типа uniqueidentifier  [new]
Minamoto
Member

Откуда: Москва
Сообщений: 1162
aleks2, согласен, я ошибся.

Заодно решает проблему с множественной вставкой.
3 июл 13, 16:23    [14517648]     Ответить | Цитировать Сообщить модератору
 Re: Вернуть @@IDENTITY дя типа uniqueidentifier  [new]
iap
Member

Откуда: Москва
Сообщений: 47142
Minamoto
aleks2, согласен, я ошибся.

Заодно решает проблему с множественной вставкой.
Но не решает проблему с триггером INSTEAD OF INSERT
3 июл 13, 16:27    [14517690]     Ответить | Цитировать Сообщить модератору
 Re: Вернуть @@IDENTITY дя типа uniqueidentifier  [new]
gds
Member

Откуда: Железнодорожный
Сообщений: 1842
Блог
Если версия сервера 2008 и выше можно так.
create table dbo.T1(
ID uniqueidentifier not null default(newsequentialid()),
Name nvarchar(5)
)
go

declare @ids table (id uniqueidentifier)

insert into dbo.T1(Name)
output inserted.ID into @ids
values (N'row1')

select top 1 id from @ids
go

В принципе как и писал aleks2.
И будет авто генерировать новые id по возрастанию, до перезагрузки сервера. После получит новую партию, может больше или меньше. Но даже если меньше то разрыв страницы кластерного индекса будет в одном месте, а с NEWID() это полностью рандомное значение. Это на случай если будут частые вставки.
3 июл 13, 22:05    [14519267]     Ответить | Цитировать Сообщить модератору
 Re: Вернуть @@IDENTITY дя типа uniqueidentifier  [new]
Mnior
Member

Откуда: Кишинёв
Сообщений: 6724
Не забывайте также прописывать ключевое слово RowGuidCol.
DECLARE @Table TABLE (
	 ID	Int			Identity	PRIMARY KEY
	,[GUID]	UniqueIdentifier	RowGuidCol	UNIQUE DEFAULT NewSequentialID()
	,Data	VarChar(1024)		NOT NULL
);
INSERT	@Table (Data)
OUTPUT	Inserted.*
VALUES ('Face'),('Palm'),('JPG');

SELECT	Scope_Identity()

SELECT	$Identity,$RowGuid,Data
INTO	#Table
FROM	@Table;

SELECT * FROM @Table;
SELECT * FROM #Table;
DROP TABLE #Table;
GO
Minamoto
declare @AccountId uniqueidentifier = NEWID()
insert into Account (AccountID, Name, Code) values (@AccountId, 'my_name', 'my_code')
Если закрыть глаза на NewID() - то подход правильный. Идентификатор должен генерироваться снаружи.
Для этого и вводился SEQUENCE для числовых типов.

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

Триггер INSTEAD OF просто отдаляет "системы" (таблицу и процедуру, к примеру), нарушая линейность. Выше указанному подходу это не помеха.
Т.е. автоинкрементный Default - зло. Точнее надо правильно им пользоваться.
3 июл 13, 23:33    [14519571]     Ответить | Цитировать Сообщить модератору
 Re: Вернуть @@IDENTITY дя типа uniqueidentifier  [new]
мимо
Guest
Mnior
Идентификатор должен генерироваться снаружи.

Не должен он генерироваться снаружи, если этот идентификатор определяет суррогатный ключ. Т.к. получается лишний объект, за которым надо следить (либо должна быть возможность жёстко привязать секванс к таблице, что в принципе уже есть через идентити ). Эта фигня в оракле присутствует: стоит где-то ошибиться и указать при генерации идентификатора не тот секванс и... абзац.
4 июл 13, 09:14    [14520263]     Ответить | Цитировать Сообщить модератору
 Re: Вернуть @@IDENTITY дя типа uniqueidentifier  [new]
Mnior
Member

Откуда: Кишинёв
Сообщений: 6724
мимо
Не должен он генерироваться снаружи, если этот идентификатор определяет суррогатный ключ.
А причём тут сурогатный ключ?

У каждой системы должен быть свой ключ. И при взаимодействии их они должны ими обмениваться. Самое простое, если эти ключи совпадают. Преимущество GUID - ключи могут совпадать в сильно гетерогенных системах и по нескольким сразу.

Если клиент посылает новые данные на вставку, то уже должен быть ключ. Не важно что после синхронизации он их перебьёт (к примеру) те что нагенерировал сервер.
Тоже самое и с процедурой и таблицей, если между ними барьер - триггер INSTEAD OF.
Разве что можно использовать иногда другие механизмы идентификации - ключ на всю группу - но это не универсально. Особенно когда надо растащить данные по разным таблам.
мимо
получается лишний объект
Поэтому некоторые извращаются - пишут ключ в другое поле, нетипичное для этого, а после перебивают нужными данными.
мимо
Эта фигня в оракле присутствует: стоит где-то ошибиться и указать при генерации идентификатора не тот секванс и... абзац.
Это вполне нормальная ситуация везде, если не используется GUID (неважно какой) - у которого свойство быть уникальным всегда и везде. Т.е. при LUID (Local Unique IDentifier) те что SEQUENCE - источник данных должен быть доверительным.
Хотя и при GUID можно накосячить - банально не генерировать кллючи, а скопировать (к примеру).
Да и коллизии могут случится.

А "абзаца" не будет - физический ключ на таблице спасёт отца русской демократии.
4 июл 13, 13:36    [14522049]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить