2009-03-19 3 views
38

Le code est le suivant:résultats SQL dynamiques dans la table temporaire dans SQL procédure stockée

ALTER PROCEDURE dbo.pdpd_DynamicCall 
@SQLString varchar(4096) = null 

AS 

Begin 

    create TABLE #T1 (column_1 varchar(10) , column_2 varchar(100)) 

    insert into #T1 
     execute ('execute ' + @SQLString) 

    select * from #T1 

End 

Le problème est que je veux appeler différentes procédures qui peuvent donner en retour des colonnes différentes. Par conséquent, je devrais définir la table # T1 génériquement. Mais je ne sais pas comment.

Quelqu'un peut-il m'aider sur ce problème?

+1

son comme vous devriez cesser d'essayer d'utiliser des procédures stockées et utiliser des scripts SQL anciens paramétrés simples. –

Répondre

34

Essayez:

SELECT into #T1 execute ('execute ' + @SQLString) 

Et ça sent vraiment mauvais comme une vulnérabilité d'injection sql.


correction (par le commentaire de @ CarpeDiem):

INSERT into #T1 execute ('execute ' + @SQLString) 

aussi, omettre le 'execute' si la chaîne SQL est autre chose qu'une procédure

+0

Difficile réponse acceptée, je ne peux pas faire ce travail! D'abord, il se plaint qu'il n'y a pas * après SELECT. Et quand je le mets, il se plaint qu'il n'y a pas de table à sélectionner. SELECT * INTO #tmp_input EXECUTE ('SELECT 1 AS test'); >>> Erreur de base de données SQL Server: doit spécifier la table à sélectionner. Sur SQL Server 2005! – ercan

+3

Je pense que la réponse était * INSERT * dans # T1 exécuter ('execute' + @SQLString) ... –

+3

Ça ne fonctionne pas ... – sreejithsdev

0

Je ne sais pas si je comprends bien, mais peut-être que vous pourriez former l'instruction CREATE dans une chaîne, puis exécuter cette chaîne? De cette façon, vous pouvez ajouter autant de colonnes que vous le souhaitez.

+0

mais, je ne connais pas les colonnes, c'est dynamique. – Dhana

31

Vous pouvez définir une table dynamique juste comme vous l'insérez dynamiquement, mais le problème est avec la portée des tables temporaires. Par exemple, ce code:

DECLARE @sql varchar(max) 
SET @sql = 'CREATE TABLE #T1 (Col1 varchar(20))' 
EXEC(@sql) 
INSERT INTO #T1 (Col1) VALUES ('This will not work.') 
SELECT * FROM #T1 

renverra l'erreur "Nom d'objet non valide" # T1 '. " C'est parce que la table temporaire # T1 est créée à un "niveau inférieur" au bloc d'exécution du code. Pour corriger, utiliser une table temporaire globale:

DECLARE @sql varchar(max) 
SET @sql = 'CREATE TABLE ##T1 (Col1 varchar(20))' 
EXEC(@sql) 
INSERT INTO ##T1 (Col1) VALUES ('This will work.') 
SELECT * FROM ##T1 

Hope this helps, Jesse

+0

en effet, cela a aidé. Je vous remercie! – user219628

+2

C'est ça! Maintenant, je peux créer la table dans ma procédure stockée, avec le nom passé via un argument! Si je pouvais donner 10 votes! –

14

Faites attention d'une solution de table temporaire globale car cela peut échouer si deux utilisateurs utilisent la même routine à la temps comme une table temporaire globale peut être vu par tous les utilisateurs ...

7
INSERT INTO #TempTable 
EXEC(@SelectStatement) 
0
DECLARE @EmpGroup INT =3 , 
     @IsActive BIT=1 

DECLARE @tblEmpMaster AS TABLE 
     (EmpCode VARCHAR(20),EmpName VARCHAR(50),EmpAddress VARCHAR(500)) 

INSERT INTO @tblEmpMaster EXECUTE SPGetEmpList @EmpGroup,@IsActive 

SELECT * FROM @tblEmpMaster 
8

créer une table temporaire globale avec un GUID au nom dynamiquement. Ensuite, vous pouvez travailler avec votre code, via dyn sql, sans craindre qu'un autre processus appelant le même sproc ne l'utilise. Cela est utile lorsque vous ne savez pas à quoi vous attendre de la table sélectionnée sous-jacente à chaque fois qu'elle s'exécute, donc vous ne pouvez pas créer explicitement une table temporaire. à savoir: - vous devez utiliser SELECT * INTO syntaxe

DECLARE @TmpGlobalTable varchar(255) = 'SomeText_' + convert(varchar(36),NEWID()) 

-- select @TmpGlobalTable 

-- build query 
    SET @Sql = 
     'SELECT * INTO [##' + @TmpGlobalTable + '] FROM SomeTable' 
EXEC (@Sql) 
EXEC ('SELECT * FROM [##' + @TmpGlobalTable + '] ') 
EXEC ('DROP TABLE [##' + @TmpGlobalTable + ']') 
PRINT 'Dropped Table ' + @TmpGlobalTable 
+0

Si vous avez des noms de colonnes dynamiques, c'est le chemin à parcourir. – jbd

+0

Bonne solution. Notez les crochets autour du nom de la table: NEWID converti en varchar contient "-" qui ne sont pas valides dans les noms d'objets sinon. – SebTHU

0
CREATE PROCEDURE dbo.pdpd_DynamicCall 
AS 
DECLARE @SQLString_2 NVARCHAR(4000) 
SET NOCOUNT ON 
Begin 
    --- Create global temp table 
    CREATE TABLE ##T1 (column_1 varchar(10) , column_2 varchar(100)) 

    SELECT @SQLString_2 = 'INSERT INTO ##T1(column_1, column_2) SELECT column_1 = "123", column_2 = "MUHAMMAD IMRON"' 
    SELECT @SQLString_2 = REPLACE(@SQLString_2, '"', '''') 

    EXEC SP_EXECUTESQL @SQLString_2 

    --- Test Display records 
    SELECT * FROM ##T1 

    --- Drop global temp table 
    IF OBJECT_ID('tempdb..##T1','u') IS NOT NULL 
    DROP TABLE ##T1 
End 
Questions connexes