web-dev-qa-db-fra.com

Variables de déclaration SQL

Quelqu'un peut-il vérifier ma déclaration ...

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)

mon erreur est ...

Msg 1087, niveau 15, état 2, ligne 1
Doit déclarer la variable de table "@tblName".

16
Argel Joseph

Votre propriété @tblName Existe à la portée externe - la portée de vos lignes de code "normales" - mais pas à la portée interne du SQL que vous construisez dans la chaîne là-bas ....

Vous devez changer vos lignes pour lire:

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

et alors ça devrait marcher très bien.

De plus, vous ne mentionnez pas votre version de SQL Server - mais à partir de SQL Server 2005 ou plus récent, vous devez cesser d'utiliser sysobjects et sysindexes - à la place, utilisez le nouveau sys schéma qui contient plus ou moins les mêmes informations - mais plus facilement disponibles. Modifiez votre requête en:

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%'''  

Voir MSDN: interrogation du catalogue système SQL Server pour beaucoup plus d'informations sur ce qui est disponible dans le nouveau schéma sys et comment en tirer le meilleur parti!

Comme l'a souligné "rsbarro": mettre cette instruction SQL ici entre guillemets est étrange - exécutez-vous également cette instruction en utilisant EXEC(...) ?? Mais comment attribuez-vous la valeur à la propriété @tblName? Ça n'a pas vraiment de sens .....

Si vous voulez réellement exécuter cette requête pour obtenir une valeur, vous devriez avoir quelque chose comme ceci:

 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%'

Vous devez avoir un TOP 1 Pour être sûr pour obtenir une seule valeur - sinon cette instruction pourrait échouer (si plusieurs lignes sont sélectionnés).

12
marc_s

Je ne sais pas exactement ce que vous essayez de faire, mais je pense que vous voulez quelque chose comme ça:

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)

Cela étant dit, il y a encore quelques choses à surveiller ici. Vous devez gérer la condition dans laquelle SELECT DISTINCT renvoie tout autre chose qu'un seul enregistrement. De plus, je ne comprends pas vraiment la nécessité de construire du SQL dynamique (dans @strSQL) quand @tblName aura toujours la même valeur (car aucune variable n'est utilisée dans la clause WHERE).

6
rsbarro