Выходные столбцы не в таблице назначения?
РЕЗЮМЕ:
Мне нужно использовать предложение OUTPUT в операторе INSERT, чтобы вернуть столбцы, которых нет в таблице, в которую я вставляю. Если я могу избежать этого, я не хочу добавлять столбцы в таблицу, в которую я вставляю.
ПОДРОБНОСТИ:
Моя таблица FinishedDocument имеет только один столбец. Это таблица, в которую я вставляю.
FinishedDocument
- DocumentID
Моя таблица документов имеет две колонки. Это таблица, из которой мне нужно вернуть данные.
Документ
- DocumentID
-- Описание
Следующее вставляет одну строку в FinishedDocument. Его предложение OUTPUT возвращает вставленный DocumentID. Это работает, но это не дает мне описание вставленного документа.
INSERT INTO FinishedDocument
OUTPUT INSERTED.DocumentID
SELECT DocumentID
FROM Document
WHERE DocumentID = @DocumentID
Мне нужно вернуть из таблицы документов и DocumentID, и описание соответствующего документа из INSERT.
Какой синтаксис мне нужен, чтобы осуществить это? Я думаю, что это возможно только с одним оператором INSERT, путем настройки предложения OUTPUT (таким образом, я явно не понимаю)?
Есть ли более умный путь, который не похож на путь, по которому я иду?
РЕДАКТИРОВАТЬ: SQL Server 2005
6 ответов
Посмотрите на Пример A:
DECLARE @temp TABLE (DocumentID int)
INSERT INTO FinishedDocument
OUTPUT INSERTED.DocumentID
INTO @temp
SELECT DocumentID
FROM Document
WHERE DocumentID = @DocumentID
SELECT Document.DocumentId, Document.Description
FROM @temp AS t
INNER JOIN Document
ON t.DocumentID = Document.DocumentID
Предложение OUTPUT может содержать любые поля, с которыми оно работает, например, в вашем случае: любые поля, в которые вы вставляете данные. Это означает, что любой из столбцов из FinishedDocument
Таблица.
Однако предложение OUTPUT не может объединять или извлекать данные из других таблиц.
Интересно, можете ли вы замаскировать это вот так (должно ли меня беспокоить, что я действительно подумал бы сделать это таким образом?):
;WITH r (DocumentID)
AS (INSERT INTO FinishedDocument
OUTPUT INSERTED.DocumentID
SELECT DocumentID
FROM Document
WHERE DocumentID = @DocumentID)
SELECT d.DocumentID, d.DocumentName
FROM Document d
JOIN r
ON d.DocumentID = r.DocumentID
Ваша вставка по-прежнему использует предложение OUTPUT, но в качестве встроенной таблицы, которая затем связывается с документом для получения необходимой информации. Хотя по какой-то причине я не могу избежать ощущения, что это безнадежно губит предложение WITH...
Оберните вставку в CTE, затем выберите и соедините вывод обратно с таблицей документов.
В 2008 году вы можете сделать это с помощью заявления MERGE. Может быть, вы могли бы рассмотреть вопрос об обновлении:)
MERGE INTO FinishedDocument
USING Document d ON 1=0
WHEN NOT MATCHED AND d.DocumentID = @DocumentID THEN
INSERT (DocumentID) VALUES (@DocumentID)
OUTPUT d.DocumentID, d.Description;
Я предлагаю вам проверить план выполнения, прежде чем попробовать это.
Стоит ли оно того? Вы вставляете только из переменной, поэтому наличие двух операторов, одного для выбора и одного для вставки, не будет стоить вам ничего лишнего. Используйте два утверждения.
Как насчет этого?
create table FinishedDocument (
DocumentId int
)
create table Document (
DocumentId int,
Description nvarchar(100)
)
create table #tmpDoc (
DocumentId int
)
insert into Document
(DocumentId, Description)
values
(1, 'Test')
insert into FinishedDocument
(DocumentId)
output Inserted.DocumentId into #tmpDoc
select D.DocumentId
from Document D
where D.DocumentId = 1
select D.DocumentId, D.Description
from #tmpDoc t
inner join Document D
on t.DocumentId = D.DocumentId
drop table #tmpDoc
drop table FinishedDocument
drop table Document