2015-07-01 3 views
0

Я работал с Access для выполнения простых запросов, но по мере увеличения сложности данных и запросов мне пришлось начать работу с MSSQL. Я изучал MSSQL с помощью проб и ошибок и, обратившись к stackoverflow, но не смог найти способ преодолеть мою последнюю стену.Не удается сохранить динамическую кросс-таблицу в таблице

Мне нужно построить кросс-таблицу динамически, но мне не удалось сохранить данные в таблице.

Для краткости Я укоротить ниже запрос:

1 IF OBJECT_ID('#TEMPF','U') IS NOT NULL DROP TABLE #TEMPF 
2 IF OBJECT_ID('#TEMPUF','U') IS NOT NULL DROP TABLE #TEMPUF 
3 IF OBJECT_ID('#TEMPVAR','U') IS NOT NULL DROP TABLE #TEMPVAR 
4 
5 SELECT * INTO #TEMPF FROM ... 
6 SELECT ROW_NUMBER() OVER (...) AS ID, * INTO #TEMPUF FROM ... 
7 
8 DECLARE @TCMAX ... 
9 DECLARE @INCREMENT MONEY ... 
10 
11 SELECT * INTO #TEMPVAR FROM #TEMPUF CROSS APPLY ... 
12 
13 DECLARE @TCUB ... 
14 DECLARE @TCLB ... 
15 DECLARE @LABEL NVARCHAR(...) 
16 DECLARE @CMD NVARCHAR(MAX) 
17 DECLARE @NUM ... 
18 
19 WHILE (@TCLB <= @TCMAX) BEGIN 
20 SET @LABEL = ... 
21 SET @CMD = N'DECLARE @INCREMENT MONEY = ' + CONVERT(NVARCHAR(...),@INCREMENT,1) + N' 
22 ALTER TABLE #TEMPUF 
23 ADD ' + @LABEL + N' FLOAT 
24 INSERT INTO #TEMPUF (' + @LABEL + N') 
25 SELECT ' + @LABEL + N' 
26 FROM #TEMPVAR 
27 CROSS APPLY 
28 (SELECT ... AS ' + @LABEL + N' FROM #TEMPF 
29 WHERE ...) AS ALIAS' 
30 EXEC(@CMD) 
31 SET @TCUB += ... 
32 SET @TCLB += ... 
33 SET @NUM += ... 
34 END 
35 
36 SELECT * FROM #TEMPUF 
37 
38 DROP TABLE #TEMPF 
39 DROP TABLE #TEMPUF 
40 DROP TABLE #TEMPVAR 
41 GO 

приведенного выше перекидного запрос недействителен столбцом сообщения об ошибке имени. Я попытался разделить @cmd [строка 21-29] в 2 @cmds, являясь первой командой alter [строка 22-23] (успех), а вторая - командой insert [строка 24-29] (сбой) , Я также пытаюсь разделить второй @cmd, выполнив команду вставки вне. Хотя команда select [строка 25-29] работает хорошо, SQL вызывает одно и то же недопустимое сообщение об ошибке имени столбца.

Это явно проблема с командой insert, но, выполняя команду select #TEMPUF, я проверил, что столбцы добавляются. Я не могу придумать решение.

Я ценю вашу помощь!

1 DECLARE @INCREMENT MONEY ... 
2 INSERT INTO #TEMPUF (BIN1) 
3 SELECT BIN1 FROM #TEMPVAR 
4 CROSS APPLY 
5 (SELECT COALESCE(CAST(COUNT(DISTINCT CONT) AS FLOAT)/NULLIF(CAST(#TEMPVAR.DCTC AS FLOAT) 
6 , 0.0), 0.0) AS BIN1 
7 FROM #TEMPF 
8 WHERE ...) AS ALIAS 
+0

Не совсем понятно, что вы здесь делаете. У меня такое чувство, что это не так эффективно, как может быть, когда я вижу кучу динамического sql внутри цикла while. Ознакомьтесь с этой статьей о динамических кросс-вкладках. http://www.sqlservercentral.com/articles/Crosstab/65048/ –

+0

В принципе, я хочу сделать крест между #TEMPVAR с #TEMPF и сохранен в последнем недавно созданном столбце в #TEMPUF. Хранение необходимо, потому что мне нужно сделать больше креста, чем может хранить тип данных NVARCHAR (MAX). – user2076517

+0

Можете ли вы отредактировать сообщение и добавить PRINT команды sql, которая генерирует ошибку, и какое имя столбца говорит об ошибке? Я вижу, что вы создаете временную таблицу в нединамическом коде, а затем пытаетесь ссылаться на нее в динамическом запросе, который, я уверен, невозможен, так как временная таблица не является глобальной. –

ответ

0

После потливости много я нашел решение для своей проблемы.

Хотя это все еще некрасиво, я изменил команду insert для команды update. У меня есть идентификатор столбца, так как #TEMPVAR создается из #TEMPUF. Пересмотренный @CMD ниже.

Спасибо всем за ваше время и силы!

21 SET @CMD = N'DECLARE @INCREMENT MONEY = ' + CONVERT(NVARCHAR(...), @INCREMENT, 0) + N'; 
22 WITH SHADOW AS (SELECT ID, ' + @LABEL + N' FROM #TEMPVAR 
23 CROSS APPLY 
24 (SELECT ... AS ' + @LABEL + N' 
25 FROM #TEMPF 
26 WHERE ...) AS ALIAS) 
27 UPDATE #TEMPUF 
28 SET ' + @LABEL + N' = SHADOW.' + @LABEL + ' 
29 FROM SHADOW 
30 WHERE #TEMPUF.ID = SHADOW.ID' 
31 EXEC(@CMD) 
Смежные вопросы