2013-07-23 18 views
6

Abbiamo un numero di stored procedure utilizzate da BizTalk per recuperare n righe da una coda (e una tabella unita) e aggiornare lo stato di tali elementi allo stesso tempo.È possibile AGGIORNARE e SELEZIONARE in singola istruzione usando la clausola OUTPUT con CTE che contiene JOIN?

Sto cercando di modificare queste query per rimuovere l'uso delle variabili di tabella e invece di eseguire il lavoro in una singola istruzione. Sono riuscito con alcuni, ma questo particolare esempio è complicato perché c'è un join nel CTE e voglio restituire alcune delle colonne unite anche se non facevano parte dello update.

Questo è quanto ho fornito con:

;with q as 
(
    select top (@FetchCount) 
     iq.InQueueId, 
     itk.[Message], 
     iq.PatNo, 
     iq.DistrictNo, 
     itk.Interaction, 
     iq.[Status] 
    from 
     InQueue iq 
     join Itk on iq.InQueueId = itk.InQueueId 
     join [Endpoint] e on iq.[Endpoint] = e.EndpointId 
     join EndpointName en on en.EndpointNameId = e.Name 
    where 
     en.Name = 'XYZ' 
     and iq.[Status] = @StatusNew 
    order by 
     iq.InQueueId 
) 
update 
    q 
set 
    [Status] = @StatusSelected 
output 
    inserted.InQueueId as [Id], 
    inserted.[Message] as [Msg], 
    inserted.DistrictNo, 
    inserted.Interaction 

Questo fallisce immediatamente con il seguente errore:

The column reference "inserted.Message" is not allowed because it refers to a base table that is not being modified in this statement.

Chiaramente questo è perché le colonne segnalare e Interaction non possono essere restituito come parte del set inserted, perché si trovano in una tabella diversa e pertanto non sono stati aggiornati.

Così ho tentato di cambiare la clausola output a:

output 
    inserted.InQueueId as [Id], 
    q.[Message] as [Msg], 
    inserted.DistrictNo, 
    q.Interaction 

questo viene a mancare con l'errore:

The multi-part identifier "q.Message" could not be bound.

E 'possibile raggiungere questo obiettivo senza dover riscrivere la query per utilizzare sia tabelle temporanee o variabili di tabella?

risposta

9

È possibile utilizzare il set deleted nella clausola di uscita per fare riferimento le colonne nel vostro CTE nelle tabelle che non vengono aggiornati

esempio

output 
    inserted.InQueueId as [Id], 
    deleted.[Message] as [Msg], 
    inserted.DistrictNo, 
    deleted.Interaction 

I deleted e inserted set in un update potrebbe anche essere pensato come prima e dopo, anche se la terminologia qui corrisponde delete...output e insert...output

+0

Grazie, che era l'unica cosa che non ho provato! Penso che avrebbero davvero potuto migliorare la scelta delle parole chiave qui; non sembra logico cercare l'insieme 'eliminato' per i valori che non sono cambiati. –

+2

Questo era esattamente ciò di cui avevo bisogno per risolvere un problema che avevo riscontrato. Vorrei poter +10 questa risposta. – Brandon