Как поместить динамический SQL в temptable, если я не знаю, какие заголовки столбцов будут созданы?

Возможный дубликат:
Как я могу назначить нормальную таблицу из динамической сводной таблицы?

У меня есть этот запрос:

DECLARE @Col NVARCHAR(MAX) = 
    (   SELECT  ', ' + QUOTENAME(CONVERT(VARCHAR, DATEADD(MONTH, DATEDIFF(MONTH, 0, CURRENT_TIMESTAMP) - (12 - Number), 0), 103)) + ' = [' + CAST(number AS VARCHAR) + ']'
        FROM    Master..spt_values
        WHERE   Type = 'P'
        AND     number BETWEEN 0 AND 12
        FOR XML PATH(''), TYPE
    ).value('.', 'NVARCHAR(MAX)')



DECLARE @SQL NVARCHAR(MAX) = 
        N'WITH Data AS
        (   SELECT  DACP_Id, DACP_Value, ResultCenters.RSL_CodDescr AS CentroResultado, Users.USR_EmpName Colaborador, Devices.DEV_NoArea+Devices.DEV_No as AreaNumero,
                    [MonthNum] = 12 - DATEDIFF(MONTH, DACP_Date, CURRENT_TIMESTAMP)
            FROM    DevicesAccompaniments INNER JOIN
                    Devices ON Devices.DEV_Id = DevicesAccompaniments.FK_DEV_Id INNER JOIN
                    ResultCenters ON ResultCenters.RSL_Id = Devices.DEV_RsltId INNER JOIN
                    Contracts ON Contracts.CNT_Id = Devices.DEV_ContrId INNER JOIN
                    Users ON Users.USR_Id = Devices.DEV_UsrId
            WHERE   DATEDIFF(MONTH, DACP_Date, CURRENT_TIMESTAMP) BETWEEN 0 AND 12 
        )   
        SELECT  CentroResultado, Colaborador, AreaNumero' + @Col + '
        FROM    Data
                PIVOT
                (   SUM(DACP_Value)
                    FOR MonthNum IN ([0], [1], [2], [3], [4], [5], [6], [7], [8], [9], [10], [11], [12])
                ) pvt;'

Он создает 12 столбцов и дополнительную информацию о 12 прошедших месяцах с нашей текущей даты, проблема в том, что мне нужно поместить этот запрос в отчет, но мне нужно отобразить столбцы в temptable с информацией внутри var @SQL без выполнение EXEC sp_executesql @SQL; Вот образец скрипки за последние 12 месяцев с текущей даты: http://www.sqlfiddle.com/

Любая помощь приветствуется, спасибо.

1 ответ

У меня есть сохраненный скрипт, который генерирует оператор вставки на основе текущей схемы (что делает его адаптивным к будущим версиям нашей базы данных). Основная идея этого заключается в том, что он объединяет данные из одной таблицы (с совершенно другой схемой, но я знаю, что у меня есть связанные данные) и использует существующую запись в таблице назначения в качестве шаблона для заполнения отсутствующих данных.

Я действительно считаю, что этот скрипт немного сложнее, чем вам нужно. Тем не менее, я думаю, что все инструменты, которые вам понадобятся, помогут вам настроить его под свои нужды.

DECLARE @SourceID VARCHAR(50), @DestinationID VARCHAR(50), @TemplateID VARCHAR(50)
-- Replace with Source ID which has menus to convert
SELECT @SourceID = '<SCREENID>' 
-- Replace with Destination container ID which will contain the parent record for the new data.
SELECT @DestinationID = '<DestinationID >' 
-- ID of template record will will be used to fill in gaps in data.
SELECT @TemplateID = '<Template Record's ID>'

-- Initialize Cursor to gather schema about destination table.
---- This should make this script schema independent
DECLARE @ColumnBuilder NVARCHAR(4000),@ColumnTemp VARCHAR(50)
select @ColumnBuilder = ''

DECLARE ColumnCursor CURSOR LOCAL
FOR select Column_Name from INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = '<DESTINATION TABLE NAME>' ORDER BY ORDINAL_POSITION

OPEN ColumnCursor

FETCH NEXT FROM ColumnCursor
INTO @ColumnTemp

WHILE @@FETCH_STATUS = 0
BEGIN

SELECT @ColumnBuilder = @ColumnBuilder + 'C.' + @ColumnTemp + ','

FETCH NEXT FROM ColumnCursor
INTO @ColumnTemp

END
CLOSE ColumnCursor
DEALLOCATE ColumnCursor
-- End Cursor

-- Modify some values, for example, we don't want to copy in the template's PK, instead we'll generate a newid()
SELECT @ColumnBuilder = SUBSTRING(@ColumnBuilder, 1,LEN(@ColumnBuilder)-1) -- get rid of last comma.

SELECT @ColumnBuilder = REPLACE(@ColumnBuilder,'C.TableID,','newid(),')
SELECT @ColumnBuilder = REPLACE(@ColumnBuilder,'C.ParentID,','''' + @DestinationID + ''',')
SELECT @ColumnBuilder = REPLACE(@ColumnBuilder,'C.ColumnINeverWantCopied,','NULL,')
SELECT @ColumnBuilder = REPLACE(@ColumnBuilder,'C.TranslateMe,','MI.TranslateableData,')
SELECT @ColumnBuilder = REPLACE(@ColumnBuilder,'C.Order,','MI.Order + C.Order,')
SELECT @ColumnBuilder = REPLACE(@ColumnBuilder,'C.EntryBy,','''TranslateScript'',')
SELECT @ColumnBuilder = REPLACE(@ColumnBuilder,'C.UpdateBy,','''TranslateScript'',')
SELECT @ColumnBuilder = REPLACE(@ColumnBuilder,'C.EntryDtm,','getdate(),')
SELECT @ColumnBuilder = REPLACE(@ColumnBuilder,'C.UpdateDtm,','getdate(),')

-- Set Label of new buttons
SELECT @ColumnBuilder = REPLACE(@ColumnBuilder,'C.Label,','
CASE WHEN MI.Alias IS NULL
THEN
CASE WHEN MI.CommandID = 7 THEN ''Dial''
WHEN MI.CommandID = 8 THEN ''Email''
ELSE S.Alias
END
ELSE MI.AlternateAlias
END,')

-- Build INSERT statement
SELECT @ColumnBuilder = 'INSERT INTO <Destination table> SELECT ' + @ColumnBuilder + ' from 
(<Source Table> MI LEFT JOIN <Source's Parent Table> S ON MI.ParentID = S.ParentID), <Destination table> C
WHERE MI.ParentID= ''' + @SourceID  + ''' AND C.TableID = ''' + @TemplateID  + ''' 
AND MI.CommandID NOT IN (25,43,32,11,45)'

-- Return whole generated statement, for debugging
SELECT @ColumnBuilder

-- Execute!
exec sp_executesql @ColumnBuilder
Другие вопросы по тегам