2009-03-27 17 views
6

Si consideri il seguente codice:TSQL Scrittura in una tabella temporanea da SQL dinamico

SET @SQL1 = 'SELECT * INTO #temp WHERE ...' 
exec(@SQL1) 
SELECT * from #temp (this line throws an error that #temp doesn't exist) 

A quanto pare questo è perché il comando exec gira fuori una sessione separata e #temp è locale per quella sessione. Posso usare una tabella temporanea globale ## temp, ma poi devo inventare uno schema di denominazione per evitare le collisioni. Cosa raccomandate tutti?

risposta

1

Non ho trovato una soluzione fattibile che abbia fatto tutto ciò di cui avevo bisogno, quindi ho scelto di utilizzare le tabelle temporali globali ##.

+10

Potrebbe causare problemi nell'ambiente multiutente – Madhivanan

+0

@Madhivanan Quali problemi? – gotqn

5

Hai provato a creare una tabella di template esplicitamente?

Create Table #temp (..) 
+4

che non risolve il problema di scoping. Tuttavia dal momento che non conosco lo schema fino a quando non viene eseguita la dichiarazione exec. (A meno che non ci sia un modo per creare una tabella senza definire uno schema?) – Jeff

+0

# ti dice che stai usando tempdb, e automaticamente si risolve in una vera tabella in tempdb con un enorme vecchio nome casuale, prevenendo i conflitti. Non è necessario il nome dello schema per emettere l'istruzione create, ma è necessario farlo al di fuori dell'SQL dinamico. –

2

È possibile creare temp prima di exec e utilizzare exec per popolare la tabella temporanea.

+2

Come si crea la tabella temporanea senza conoscere lo schema? (La mia selezione definisce lo schema) – Jeff

1

In alternativa, è possibile utilizzare una variabile di tabella.

Ecco un buon article per discuterne.

+1

Questo non risolve il problema, non puoi 'SELEZIONARE ... INTO' una variabile di tabella e se l'OP ha uno schema di tabella statico noto in anticipo potrebbero altrettanto facilmente usare un' CREATE TABLE # temp' statement. Il suggerimento variabile della tabella non fornisce funzionalità aggiuntive. –

0

Non è possibile inserire la selezione dopo l'inserimento in a; delimitare e gestire insieme le due dichiarazioni?

5

Prova ## temp Poiché la query dinamica viene eseguita su un'altra fibra in modo da non poter vedere la tabella temporanea locale. invece se dichiari la tua tabella temporanea come globale, diventa sensata.

1

Un esempio, guarda "in"

SELECT o.OrderID, o.OrderDate, od.UnitPrice, od.Quantity, 
     c.CustomerID, c.CompanyName, c.Address, c.City, c.Region, 
     c.PostalCode, c.Country, c.Phone, p.ProductID, 
     p.ProductName, p.UnitsInStock, p.UnitsOnOrder 
INTO #temp 
FROM Orders o 
JOIN [Order Details] od ON o.OrderID = od.OrderID 
JOIN Customers c ON o.CustomerID = c.CustomerID 
JOIN Products p ON p.ProductID = od.ProductID 
0

Un altro metodo è quello di utilizzare tutto il codice all'interno del SQL dinamico

SET @SQL1 = 'SELECT * INTO #temp WHERE ... 
SELECT * from #temp ' 
exec(@SQL1) 
0

V'è un metodo per creare manichino tabella temporanea con singolo colonna Identity, quindi alterando quella tabella con lo schema desiderato tramite SQL dinamico e popolandolo. In questo modo è possibile utilizzare tabella temporanea sia in dinamica e regolare SQL, unirsi con esso ...

-- Create dummy table 
CREATE TABLE #tmpContactData (PK int NOT NULL IDENTITY(1,1)) 

-- Alter its schema 
DECLARE @sqlCommand nvarchar(max) 
SELECT @sqlCommand = ' 
ALTER TABLE #tmpContactData 
ADD 
    EmployeeId int, 
    Address varchar(100), 
    Phone varchar(50) 
' 
EXECUTE(@sqlCommand) 

-- Fill it 
SELECT @sqlCommand = ' 
INSERT INTO #tmpContactData 
SELECT t.EmployeeId, t.Address, t.Phone 
FROM ( SELECT EmployeeId=1000, Address=''Address 1000'', Phone=''Phone 1000'' 
     UNION 
     SELECT 1001, ''Address 1001'', ''Phone 1001'' 
     UNION 
     SELECT 1002, ''Address 1002'', ''Phone 1002'' 
) t 
' 
EXECUTE(@sqlCommand) 

--select from it 
SELECT * FROM #tmpContactData 

--CleanUp 
DROP TABLE #tmpContactData 
Problemi correlati