Выходные столбцы не в таблице назначения?

РЕЗЮМЕ:
Мне нужно использовать предложение 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
Другие вопросы по тегам