2009-04-22 6 views
4

J'ai vu this, donc je sais comment créer un tableau croisé dynamique avec un ensemble de champs générés dynamiquement. Mon problème maintenant est que je voudrais obtenir les résultats dans une table temporaire.Obtention d'un tableau croisé dynamique généré dynamiquement dans une table temporaire

Je sais que pour obtenir le jeu de résultats dans une table temporaire à partir d'une instruction EXEC, vous devez prédéfinir la table temporaire. Dans le cas d'un tableau croisé dynamique généré dynamiquement, il n'y a aucun moyen de connaître les champs à l'avance.

La seule façon que je peux envisager pour obtenir ce type de fonctionnalité est de créer une table permanente en utilisant SQL dynamique. Y a-t-il un meilleur moyen?

Répondre

1

vous pouvez le faire:

-- add 'loopback' linkedserver 
if exists (select * from master..sysservers where srvname = 'loopback') 
    exec sp_dropserver 'loopback' 
go 
exec sp_addlinkedserver @server = N'loopback', 
    @srvproduct = N'', 
    @provider = N'SQLOLEDB', 
    @datasrc = @@servername 
go 

declare @myDynamicSQL varchar(max) 
select @myDynamicSQL = 'exec sp_who' 
exec(' 
    select * into #t from openquery(loopback, ''' + @myDynamicSQL + '''); 
    select * from #t 
    ') 

EDIT: addded sql dynamique pour accepter params à Openquery

+0

Comment passez-vous le SQL dynamique à OPENQUERY? – brian

+0

vous ne le faites pas. tu devras faire cette dynamique aussi. –

+0

Je ne comprends pas, veuillez clarifier – brian

1

Permettez-moi cette explication de sélection en place. Je cours également SQL Server 2005. Parce que vous avez des tableaux croisés dynamiques, je vais prendre la même ou 2008.

select 
    o.*, 
    OtherField1, 
    OtherField2 
INTO #temp 
FROM 
    OriginalOtherData as ood 
PIVOT (
    MAX([Value]) 
    FOR Field in (OtherField1, OtherField2) 
) as piv 
RIGHT OUTER join 
    Original o on o.OriginalSD = piv.OriginalSD 

select * from #temp 
Drop table #temp 

La seule différence entre une sélection normale et une sélection en est que dans la partie #table.

+0

S'il vous plaît lisez la question liée. J'utilise SQL dynamique pour générer la liste des champs pour la table pivotée. Vous ne pouvez pas utiliser SELECT INTO avec un EXEC sauf si vous avez déjà créé une table. Comme je ne connais pas la liste des champs du résultat de l'EXEC, je ne peux pas précréer la table. – brian

+0

Vous générez déjà dynamiquement la liste des champs. Alors pourquoi ne pas utiliser ce code pour aider à générer la définition de la table? De même, y a-t-il quelque chose qui empêche MSSQL de faire votre SELECT INTO dans l'EXEC, et pas en dehors de celui-ci? – Min

+0

La réponse à ces deux questions est que la portée d'une table temporaire créée à l'intérieur d'une requête SQL dynamique la rendrait inaccessible à la procédure/requête qui a effectué l'appel EXEC. – brian

0
  • pour la requête (sélectionnez col1, col2, col3 de tablename
  • col1 devient rowlabels
  • col2 devient ColumnHeaders
  • col3 est le jeu de données

  • supprime aussi la table mondiale

    if OBJECT_ID('tempdb..#3') is not null drop table #3 
    if OBJECT_ID('tempdb..##3') is not null drop table ##3 
    DECLARE @cols AS NVARCHAR(MAX), 
        @query AS NVARCHAR(MAX) 
    select @cols = STUFF((SELECT distinct ',' + QUOTENAME( col2 ) from tablename FOR XML PATH(''), col2).value('.', 'NVARCHAR(MAX)'),1,1,'') 
    set @query = 'SELECT col1, ' + @cols + ' into ##3 from (select col1, col2, col3 from tablename) x pivot ( max(col3)for col2 in (' + @cols + ')) p ' 
    execute(@query) 
    select * into #3 from ##3 if OBJECT_ID('tempdb..##3') -- is not null drop table ##3 
    
1

Ran dans ce numéro aujourd'hui, et posté sur mon blog. Brève description de la solution, est de créer une table temporaire avec une colonne, puis ALTER dynamiquement en utilisant sp_executesql. Vous pouvez ensuite insérer les résultats du PIVOT dynamique dans celui-ci. Exemple de travail ci-dessous.

CREATE TABLE #Manufacturers 
(
    ManufacturerID INT PRIMARY KEY, 
    Name VARCHAR(128) 
) 

INSERT INTO #Manufacturers (ManufacturerID, Name) 
VALUES (1,'Dell') 
INSERT INTO #Manufacturers (ManufacturerID, Name) 
VALUES (2,'Lenovo') 
INSERT INTO #Manufacturers (ManufacturerID, Name) 
VALUES (3,'HP') 

CREATE TABLE #Years 
(YearID INT, Description VARCHAR(128)) 
GO 

INSERT INTO #Years (YearID, Description) VALUES (1, '2014') 
INSERT INTO #Years (YearID, Description) VALUES (2, '2015') 
GO 

CREATE TABLE #Sales 
(ManufacturerID INT, YearID INT,Revenue MONEY) 
GO 

INSERT INTO #Sales (ManufacturerID, YearID, Revenue) VALUES(1,2,59000000000) 
INSERT INTO #Sales (ManufacturerID, YearID, Revenue) VALUES(2,2,46000000000) 
INSERT INTO #Sales (ManufacturerID, YearID, Revenue) VALUES(3,2,111500000000) 
INSERT INTO #Sales (ManufacturerID, YearID, Revenue) VALUES(1,1,55000000000) 
INSERT INTO #Sales (ManufacturerID, YearID, Revenue) VALUES(2,1,42000000000) 
INSERT INTO #Sales (ManufacturerID, YearID, Revenue) VALUES(3,1,101500000000) 
GO 

DECLARE @SQL AS NVARCHAR(MAX) 
DECLARE @PivotColumnName AS NVARCHAR(MAX) 
DECLARE @TempTableColumnName AS NVARCHAR(MAX) 
DECLARE @AlterTempTable AS NVARCHAR(MAX) 

--get delimited column names for various SQL statements below 
SELECT 
    -- column names for pivot 
    @PivotColumnName= ISNULL(@PivotColumnName + N',',N'') + QUOTENAME(CONVERT(NVARCHAR(10),YearID)), 
    -- column names for insert into temp table 
    @TempTableColumnName = ISNULL(@TempTableColumnName + N',',N'') + QUOTENAME('Y' + CONVERT(NVARCHAR(10),YearID)), 
    -- column names for alteration of temp table 
    @AlterTempTable = ISNULL(@AlterTempTable + N',',N'') + QUOTENAME('Y' + CONVERT(NVARCHAR(10),YearID)) + ' MONEY' 
FROM (SELECT DISTINCT [YearID] FROM #Sales) AS Sales 

CREATE TABLE #Pivot 
(
    ManufacturerID INT 
) 

-- Thats it! Because the following step will flesh it out. 

SET @SQL = 'ALTER TABLE #Pivot ADD ' + @AlterTempTable 
EXEC sp_executesql @SQL 

--execute the dynamic PIVOT query into the temp table 
SET @SQL = N' 
    INSERT INTO #Pivot (ManufacturerID, ' + @TempTableColumnName + ') 
    SELECT ManufacturerID, ' + @PivotColumnName + ' 
    FROM #Sales S 
    PIVOT(SUM(Revenue) 
     FOR S.YearID IN (' + @PivotColumnName + ')) AS PivotTable' 
EXEC sp_executesql @SQL 

SELECT M.Name, P.* 
FROM #Manufacturers M 
INNER JOIN #Pivot P ON M.ManufacturerID = P.ManufacturerID 
+0

Bonne étude de cas complète étape par étape. Le lien de votre blog ne fonctionne pas de toute façon. – vibs2006

+0

@ vibs2006 - lien fixe, merci – KnarfaLingus