2012-02-23 14 views
16

chiunque può controllare sul mio estratto ...SQL dichiarare le variabili

DECLARE @tblName varchar(MAX), 
     @strSQL varchar(MAX) 

SET @tblName ='SELECT DISTINCT o.name as TableName 
       FROM sysobjects o 
       JOIN sysindexes x on o.id = x.id 
       WHERE o.name LIKE ''%empty%''' 

SET @strSQL = 'INSERT INTO @tblName VALUES(''trylng'', ''1'')' 
EXEC (@strSQL) 

il mio errore è ...

Msg 1087, livello 15, stato 2, riga 1
Deve dichiarare la variabile di tabella "@tblName".

+3

Spero ci siano solo due colonne in qualunque tabella venga restituita, e il tipo di dati corrisponde ... –

+0

@OMGPonies: intendi colonne inseribili, ovviamente. –

risposta

6
Non

sicuro esattamente quello che stai cercando di fare, ma penso che si desidera qualcosa di simile:

DECLARE @tblName varchar(MAX), @strSQL varchar(MAX) 
SET @tblName = 
    (select distinct o.name as TableName 
    from sysobjects o 
    join sysindexes x on o.id = x.id 
    where o.name LIKE '%empty%') 
SET @strSQL = 'INSERT INTO [' + @tblName + '] VALUES(''trylng'', ''1'')' 
exec (@strSQL) 

Detto questo, ci sono ancora un paio di cose da guardare fuori per qui. È necessario gestire la condizione in cui lo SELECT DISTINCT restituisce qualcosa di diverso da un singolo record. Inoltre, non capisco la necessità di creare SQL dinamico (in @strSQL) quando @tblName avrà sempre lo stesso valore (poiché non ci sono variabili utilizzate nella clausola WHERE).

+1

+1, solo una nota: in genere è più sicuro incorporare i nomi in script dinamici come questo: "INSERT INTO" + QUOTENAME (@tblName) + "..." ", piuttosto che semplicemente racchiudere tra parentesi quadre. –

+0

grazie per le informazioni Andriy –

+0

@AndriyM: Cool, grazie per il suggerimento! – rsbarro

12

La tua struttura @tblName esiste l'ambito esterno - l'ambito delle linee di codice "normale" - ma non a portata interna del SQL si sta costruendo nella stringa di lì ....

È necessario per modificare le righe da leggere:

SET @strSQL = 'INSERT INTO ' + @tblName + ' VALUES(''trylng'', ''1'')' 

e quindi dovrebbe funzionare bene.

Inoltre, non stai citano la versione di SQL Server - ma a partire da SQL Server 2005 o più recente, si dovrebbe smettere di usare sysobjects e sysindexes - invece, utilizzare il nuovo sys schema che contiene più o meno le stesse informazioni - ma più facilmente disponibile. Modificare la tua ricerca per:

SET @tblName ='SELECT DISTINCT t.name as TableName 
       FROM sys.tables t 
       INNER JOIN sys.indexes i on i.object_id = t.object_id 
       WHERE t.name LIKE ''%empty%''' 

Vedere MSDN: Querying the SQL Server System Catalog per molte più informazioni su ciò che è disponibile nella nuova sys schema e come fare la maggior parte di essa!

Come "rsbarro" ha sottolineato: mettere questa dichiarazione SQL qui tra virgolette è strano - stai eseguendo questa affermazione usando EXEC(...), anche ?? Ma come si assegna il valore alla proprietà @tblName? Non ha molto senso .....

Se si desidera eseguire in realtà questa query per ottenere un valore, si dovrebbe avere qualcosa di simile:

SELECT TOP 1 @tblName = t.name 
FROM sys.tables t 
INNER JOIN sys.indexes i on i.object_id = t.object_id 
WHERE t.name LIKE '%empty%' 

È necessario disporre di un TOP 1 in là essere sicuro per ottenere solo un singolo valore - altrimenti questa dichiarazione potrebbe fallire (se sono selezionate più righe).

+0

Mi manca qualcosa? Perché @tblName è racchiuso tra virgolette singole? Non sarà sufficiente impostarlo uguale alla stringa e non al nome della tabella? – rsbarro

+0

No, intendo la seconda affermazione. Non dovrebbe leggere 'SET @tblName = SELECT DISTINCT t.name ...' senza virgolette? Il modo in cui è scritto @strSQL avrà un valore di 'INSERT INTO SELECT DISTINCT t.Name come TableName ...'. Mi sembra che non sarà valido, no? – rsbarro

+0

@rsbarro: ah ok - beh, non sono sicuro - stavo dando per scontato che l'OP esegua quella istruzione SQL usando 'EXEC (....)'. Se no, allora hai assolutamente ragione, non funzionerà! –

Problemi correlati