2015-10-19 1 views
2

Je suis en train de créer une table temporaire avec un nombre dynamique de colonnes:Créer table temporaire avec un nombre dynamique de colonnes

set @cmd = ' SELECT * into #temp3 from 
      (
       select * from sometable 
      ) x pivot 
      (
       max(buildrate) 
       for name in ('+ @columns +') 
      ) as y ' 

execute(@cmd); 

select * from #temp3 left join performed in an elegant way... 

et je dois utiliser le contenu de cette table dans un autre traitement.

Y at-il un moyen raisonnable de le faire?

+1

lien obligatoire à sommarskog.se: http://www.sommarskog.se/dynamic_sql.html#unknowncolumns Lire l'article pour obtenir enlightend sur SQL dynamique. –

+1

Almoust a fermé la page quand j'ai atteint cette "Si vous travaillez avec une base de données relationnelle, et que vous ne connaissez pas la structure de vos données avant l'exécution, il y a quelque chose de fondamentalement faux." –

+0

C'est exactement le modèle (pivot) qui nécessite que ce problème de portée de table temporaire soit traité par Microsoft dans une future version de SQL Server. –

Répondre

1

Une solution consiste à utiliser la table temporaire globale:

SET @cmd = ' SELECT * INTO ##temp3 FROM 
      (
       select * from sometable 
      ) x pivot 
      (
       max(buildrate) 
       for name in ('+ @columns +') 
      ) as y ' 

EXECUTE(@cmd); 

SELECT * 
INTO #temp3 
FROM ##temp3; 

DROP TABLE ##temp3; 

SELECT * 
FROM JOIN #temp3 
LEFT ...; 

La table temporaire locale normale ne fonctionnera pas, parce que SQL dynamique crée un nouveau contexte. La table est dans ce contexte et cessera d'exister quand le code est exécuté, donc vous ne pouvez pas l'utiliser en dehors de Dynamic-SQL.

+1

que faire si cette procédure sera appelée par plusieurs utilisateurs simultanément? Peut-il y avoir une situation où nous allons insérer dans # temp3 quand ## temp3 sera supprimé? – Muflix

+0

juste pour des raisons de débat: vous pouvez utiliser une table "réelle" au lieu de # temp3 et ne jamais supprimer la table réelle. Et pour gérer la situation multi-utilisateur il suffit d'ajouter une colonne de nom d'utilisateur dans cette table et peut-être supprimer les données précédentes pour toutes les nouvelles demandes. J'espère simplement que je n'aurai pas de collègue qui aura cette approche. –

0

Sur la base de commentaires @Ocaso Protal, j'ai créé cette

-- create global temporary table with timestamp to prevent multiple user collision 
DECLARE @timestamp NVARCHAR(255) = REPLACE(REPLACE(REPLACE(REPLACE(CONVERT(NVARCHAR(23), GETDATE(), 121),'-',''),' ',''),':',''),'.','') 
DECLARE @temp NVARCHAR(255) = '##temp_'[email protected] 
SET @query = 'CREATE TABLE ' + @temp + ' (RowName NVARCHAR(255), ' + @outputQueryColumns + ')' 
EXECUTE sp_executesql @query 

-- working with temporary table whether in procedure or in dynamic sql 

-- delete global temporary table 
SET @query = 'DROP TABLE ' + @temp 
EXECUTE sp_executesql @query 
+2

ne serait pas plus simple de faire quelque chose comme '## temp_' + MD5 (getdate())? ;) –

+0

oui, merci :-) – Muflix