2017-01-23 14 views
0

Я пытаюсь создать временную таблицу с динамическим числом столбцов на основе количества строк из другой таблицы temp. Скажем, у меня 89 строк в # таблице1, в # таблице2 я хотел бы использовать счетчик строк и принять это значение соответствующей строки в качестве имени столбца. Я занимаюсь этим некоторое время, но я продолжаю получать ошибки. Вот мой запрос, который позже будет передан в proc.Динамически добавлять столбцы в временную таблицу на основе строк в другой таблице temp

Моя таблица выглядит следующим образом (все столбцы VARCHAR с нулем допускается в случае, если импортируемая дата не имеет никаких данных для этого CVE номера - CVEId относитс к FK ограничения CVEID на CVENumber таблице):

CVEId  D20160901  D20160902  D20160903  D20160904  D20160905 
1   6182   6473   5879   NULL   NULL 
2   72862   76583   NULL   NULL   74772 

CVENumber Table: 
CVEID  CVENumber 
1   CVE-781-2016 
2   CVE-006-2016 

Я В надежде получить дату столбца или, возможно, использовать введенную дату в качестве первой строки - запустить запрос по этим данным, где я могу указать 09-01-2016 по 09-03-2016. И верните все строки из таблицы с CVENumber, указанным в таблице CVENumber. На что я хочу, чтобы мой результат выглядел так:

CVE Number  09-01-2016  09-02-2016  09-03-2016 
CVE-781-2016   6182   6473   8579 
CVE-006-2016  72682   76583    0 

Надеюсь, это разъяснит, что я пытаюсь сделать.

Мой текущий запрос с использованием STUFF(), который берет строки из #FixedDates и превращает их в столбцы. Я хочу взять эти столбцы возвращены @cols быть добавлены в качестве столбцов #query_results

Set nocount on 

Insert #tmp 
EXEC sp_columns @table_name = N'CVECountsByDate' 

-- Using collate to force the DB to only look at Uppercase values 
DECLARE @cols varchar(max), @query varchar(max), @cols2 varchar(MAX) 

INSERT #FixedDays 
SELECT Replace(COLUMN_NAME, 'D' collate Latin1_General_CS_AS, '' collate Latin1_General_CS_AS) from #Tmp 
WHERE COLUMN_NAME LIKE 'D%' collate Latin1_General_CS_AS OR COLUMN_NAME = 'CVEId' ORDER BY COLUMN_NAME DESC 


SET @cols = STUFF((SELECT ',' + QUOTENAME(QT.COLUMN_NAME) + ' varchar(100)' 
       FROM #FixedDays QT 
       GROUP BY QT.COLUMN_NAME 
       ORDER BY QT.COLUMN_NAME 
       FOR XML PATH(''), TYPE 
       ).value('.', 'VARCHAR(MAX)') 
       ,1,1,'') 

SET @cols2 = N'CREATE TABLE #query_results (' + @cols + ') ' 
--EXEC(@cols2) 
SELECT @cols2 

DROP TABLE #FixedDays 
DROP TABLE #Tmp 
+0

Почему бы вам не желаете, чтобы быть строки вместо новых столбцов? У нормализованных данных для работы намного проще для всего, что вам нужно делать с этими данными. –

+0

Формат этих столбцов [не мой дизайн] похож на формат даты, но вот так: 1 сентября 2016 года в имени столбца находится D20160901. Я пытаюсь взять имя этого столбца и преобразовать его в 09-01-2016. Хранимая процедура используется для создания отчета. Я ищу, чтобы создать временную таблицу с датами в правильном формате и передать два параметра для начала и окончания дат. – bbcompent1

+0

Это звучит как динамическая ось или динамическая перекрестная вкладка, которая будет лучшим решением, чем попытка настроить таблицу темпа, подобную этой. –

ответ

0

Это то, что я в конечном итоге делает ...

CREATE TABLE #Tmp 
(TABLE_QUALIFIER varchar(40), 
    TABLE_OWNER varchar(20), 
    TABLE_NAME varchar(40), 
    COLUMN_NAME varchar(40), 
    DATA_TYPE int, 
    TYPE_NAME varchar(20), 
    PREC int, LENGTH int, 
    SCALE int, RADIX int, 
    NULLABLE char(4), 
    REMARKS varchar(128), 
    COLUMN_DEF varchar(40), 
    SQL_DATA_TYPE int, 
    SQL_DATETIME_SUB int, 
    CHAR_OCTET_LENGTH int, 
    ORDINAL_POSITION int, 
    IS_NULLABLE char(4), 
    SS_DATA_TYPE int) 
CREATE TABLE #FixedDays 
(COLUMN_NAME varchar(40)) 
CREATE TABLE #query_results 
(CVENumber varchar(100) null) 
Set nocount on 
Insert #tmp 
EXEC sp_columns @table_name = N'CVECountsByDate' 
INSERT #FixedDays 
SELECT Replace(COLUMN_NAME, 'D' collate Latin1_General_CS_AS, '' collate Latin1_General_CS_AS) from #Tmp 
WHERE COLUMN_NAME LIKE 'D%' collate Latin1_General_CS_AS OR COLUMN_NAME = 'CVEId' 
DECLARE @listStr VARCHAR(MAX) 
DECLARE @FixedList VARCHAR(MAX) 
SELECT @FixedList = COALESCE(@FixedList,'[') + COLUMN_NAME + '] VARCHAR(MAX) NULL, [' FROM #FixedDays 
SELECT @FixedList = substring(@FixedList, 1, len(@FixedList) -1) 
SET @FixedList = LEFT(@FixedList, len(@FixedList)-1) -- Altered Column List 
EXEC(N'ALTER TABLE #query_results ADD ' + @FixedList + '') 
INSERT INTO #query_results 
SELECT CVEDetails.CVENumber, CVECountsByDate.* FROM CVECountsByDate INNER JOIN CVEDetails ON CVECountsByDate.CVEId = CVEDetails.CVEID 
ALTER TABLE #query_results DROP column CVEId 

DROP TABLE #query_results 
DROP TABLE #Tmp 
DROP TABLE #FixedDays