2015-12-08 9 views
0

Я хочу выбрать обратно данные, которые я только что вставил в базу данных. Я знаю, что OUTPUT можно использовать, и мы можем вызвать INSERTED. [ColumnName], чтобы захватить значения, которые были вставлены. Могут ли эти значения задаваться какой-либо переменной или иметь псевдоним? Я не хочу использовать таблицу TEMP, потому что я хочу использовать переменные, если это возможно.SQL Return Введенные данные

Было бы хорошо, если бы решение работало, когда ПК является или не является столбцом идентификации.

EDIT: Contacts.PhoneNumberID является внешним ключом к PhoneNumber.ID я хочу сделать как вставку заявления спина к спине, и мне нужно идентификатор из PhoneNumber использовать для Contacts.PhoneNumberID

EDIT:. [PhoneNumber] [ID] имеет значение по умолчанию, указанное в базе данных, то есть, как идентификатор создается

Вот что я ищу:

INSERT INTO [PhoneNumber] (Number) 
OUTPUT INSERTED.ID, INSERTED.Number 
VALUES ('555-555-5555') 

INSERT INTO [Contacts] (Name,PhoneNumberID) 
VALUES ('SomeName', {ID From previous insert}) 

Можно ли как некоторые псевдоним заявления вставки сказать:

INSERT INTO [PhoneNumber] (Number) 
OUTPUT INSERTED.ID, INSERTED.Number 
VALUES ('555-555-5555') as A 

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

Тогда вы могли бы сделать это:

INSERT INTO [Contacts] (Name,PhoneNumberID) 
VALUES ('SomeName', A.ID) 

Я иду за конечный результат чего-то похожее на это:

INSERT INTO [PhoneNumber] (Number) 
OUTPUT INSERTED.ID, INSERTED.Number 
VALUES ('555-555-5555') as A 

INSERT INTO [Contacts] (Name,PhoneNumberID) 
VALUES ('SomeName', A.ID) 

Причина Я пытаюсь сделать это:

Я хочу поставить обоих вкладчиков ts в транзакционном блоке, если один из них терпит неудачу, то я могу откатить и ничего не совершить.

+3

Я не понимаю ваш вопрос или что вы пытаетесь сделать здесь. Что такое псевдоним? Если вы хотите, чтобы несколько операторов были частью транзакции, вы просто добавляете оба оператора внутри транзакции. Лучшим подходом было бы обернуть все это внутри блока try/catch. –

+0

Извинения. Я добавил изменение относительно того, почему я пытаюсь это сделать. Все это основано на внешних ключах, и мне нужна PK из первой таблицы, чтобы вставить во вторую таблицу. – TheMiddleMan

+0

Я знаю, что вы упомянули о попытке решить эту проблему без таблицы 'TEMP', однако [это решение] (http: // stackoverflow .com/a/10999467/3854195), используя переменную таблицы, будет работать так, как вы описали. – Morpheus

ответ

1

Для этого вам нужно использовать IDENT_CURRENT ('your_table) функция. Он возвращает последнее значение IDENTITY, созданное в таблице, независимо от соединения, которое создало значение, и независимо от области действия оператора, который произвел значение. IDENT_CURRENT не ограничивается областью действия и сеансом; он ограничен указанной таблицей. IDENT_CURRENT возвращает значение идентификатора, сгенерированное для конкретной таблицы, в любом сеансе и в любой области. Так что ваш код будет выглядеть следующим образом:

Declare @last_ident numeric(38,0) 
INSERT INTO [PhoneNumber] (Number) 
VALUES ('555-555-5555') 

SELECT @last_ident = IDENT_CURRENT('PhoneNumber') 

INSERT INTO [Contacts] (Name,PhoneNumberID) 
VALUES ('SomeName', @last_ident) 

Более подробную информацию вы можете найти here

EDIT:

Если вам нужно, чтобы получить нон поле идентификатора следует использовать выход и

Declare @tbl table(ID int) 
INSERT INTO [PhoneNumber] (Number) 
OUTPUT INSERTED.ID INTO @tbl 
VALUES ('555-555-5555') 

Declare @id int 
select @id = ID from @tbl 

INSERT INTO [Contacts] (Name,PhoneNumberID) 
VALUES ('SomeName',@id) 
+0

Это близко, но это кажется, работает только в том случае, если PK - это столбец Identity – TheMiddleMan

+0

. Что представляет собой ваш ПК? – Yuri

+0

PhoneNumber.ID - это мой ПК. Это отлично работает, когда идентификатор является столбцом Identity, но если он не является, он просто возвращает null. Я пересмотрел свой вопрос выше, чтобы заявить, что я хотел бы, чтобы возможный ответ на работу, когда ПК является и не является столбцом идентификации. Это похоже на временную таблицу, это единственный способ. – TheMiddleMan

0

Вы можете скачать последнюю версию с SCOPE_IDENTITY(). Так что ваш код может выглядеть так:

DECLARE @id AS INT; 
INSERT INTO [PhoneNumber] (Number) 
VALUES ('555-555-5555') 

SELECT @id = SCOPE_IDENTITY(); 

INSERT INTO [Contacts] (Name,PhoneNumberID) 
VALUES ('SomeName', @id) 

Для DECLARE @id AS INT; вам необходимо изменить тип переменной, чтобы соответствовать PhoneNumberID столбец типа данных

+0

Будет ли SCOPE_IDENTITY() работать с несколькими ключами, если они есть? – TheMiddleMan

+2

@ user3329760 'SCOPE_IDENTITY' работает только в столбце' IDENTITY'. Поэтому он может работать только на одном столбце (поле идентификации должно быть первичным ключом) –

+0

Нет, вы должны использовать предложение OUTPUT в противном случае с помощью таблицы temp, я думаю ... – Thomas

0

Вы также можете использовать Sequence.

Declare @newId int = NEXT VALUE FOR [PhoneNumber_Seq]; 
Insert into [PhoneNumber] (ID, Number) 
values(@newId, '555-555-55555') 

INSERT INTO [Contacts] (Name,PhoneNumberID) 
VALUES ('SomeName', @newId) 
+0

Неплохо, но работает только с SQL 2012 и выше – Yuri

Смежные вопросы