2011-08-11 8 views
5

열 이름이 동적으로 생성되는 피벗 테이블 요소에 쿼리를 쓰고 있습니다.SQL Azure에서 임시 테이블 사용

SET @query = N'SELECT STUDENT_ID, ROLL_NO, TITLE, STUDENT_NAME, EXAM_NAME, '+ 
      @cols + 
      ' INTO ##FINAL 
      FROM 
      (
       SELECT * 
       FROM #AVERAGES 
       UNION 
       SELECT * 
       FROM #MARKS 
       UNION 
       SELECT * 
       FROM #GRACEMARKS 
       UNION 
       SELECT * 
       FROM #TOTAL 
       ) p 
       PIVOT 
       (
       MAX([MARKS]) 
       FOR SUBJECT_ID IN 
       ('+ 
       @cols +') 
      ) AS FINAL 
      ORDER BY STUDENT_ID ASC, DISPLAYORDER ASC, EXAM_NAME ASC;' 

EXECUTE(@query) 

select * from ##FINAL 

이 쿼리는 로컬 데이터베이스에서 제대로 작동하지만 SQL Azure에서는 전역 임시 테이블이 허용되지 않으므로이 쿼리는 작동하지 않습니다.

지금 난 내 로컬 데이터베이스에 #FINAL-##FINA L를 변경하는 경우,하지만

잘못된 개체 이름으로 나에게 오류를 제공 '#FINAL'.

이 문제를 어떻게 해결할 수 있습니까?

+0

SQL에서 잘 지원되지 않는 무언가 (결과 집합이 가변 개수 인 결과)를 구성하려고하므로 특정 문제가 해결되지 않을 것으로 생각됩니다. 일반적인 경우,이 작업을 수행하려면 외부 범위 (예 : EXECUTE) 이전에 임시 테이블을 만들어야하지만, 열이 무엇인지 모를 때는 임시 테이블을 만들 수 없습니다 필요할 것입니다. –

+0

사실 나는 이미 그것을 시험해 보았고, 나는 temp를 만들었고 @에있는 열 이름을 넣었다. 그것은 in 절에서 사용할 수 없기 때문에 어떤 용도로도 사용되지 않습니다. 즉, FOR SUBJECT_ID IN (SELECT cast (subject_id AS NVARCHAR) from #SUBJECT_ID_TABLE) –

+0

아니요, 요점은 'EXECUTE'이전에 '# Final'임시 테이블을 만드는 것이 었습니다 - 두 스코프 모두에서 액세스 할 수있는 유일한 방법입니다 . 내 대답에서 작동 할 수있는 한 가지 방법을 보여 줬습니다. –

답변

10

좋아, 내가 할 수 있다고 생각하지 않는다고 말한 후에, 나는 길을 가질 수있다. 그래도 추한 데. 바라건대, 당신이 아래의 샘플을 재생할 수 있습니다 귀하의 질의에 적응 (내가 그것을 쓰기를 시도하는 스키마 및 데이터를하지 않고, 너무 까다로운) :

declare @cols varchar(max) 
set @cols = 'object_id,schema_id,parent_object_id' 

--Create a temp table with the known columns 
create table #Boris (
    ID int IDENTITY(1,1) not null 
) 
--Alter the temp table to add the varying columns. Thankfully, they're all ints. 
--for unknown types, varchar(max) may be more appropriate, and will hopefully convert 
declare @tempcols varchar(max) 
set @tempcols = @cols 
while LEN(@tempcols) > 0 
begin 
    declare @col varchar(max) 
    set @col = CASE WHEN CHARINDEX(',',@tempcols) > 0 THEN SUBSTRING(@tempcols,1,CHARINDEX(',',@tempcols)-1) ELSE @tempcols END 
    set @tempcols = CASE WHEN LEN(@col) = LEN(@tempcols) THEN '' ELSE SUBSTRING(@tempcols,LEN(@col)+2,10000000) END 
    declare @sql1 varchar(max) 
    set @sql1 = 'alter table #Boris add [' + @col + '] int null' 
    exec (@sql1) 
end 

declare @sql varchar(max) 
set @sql = 'insert into #Boris (' + @cols + ') select ' + @cols + ' from sys.objects' 
exec (@sql) 

select * from #Boris 

drop table #Boris 

그들은 키는 임시 테이블을 만드는 것입니다 바깥 쪽 범위에서 내부 범위 (EXEC 문 내에서 실행되는 코드)는 동일한 임시 테이블에 액세스 할 수 있습니다. 위의 내용은 SQL Server 2008에서 작동했지만 Azure 인스턴스가 없으므로 테스트하지 않았습니다.

+0

이 작업을 시도했는데 올바른 결과가 나오는 한 좀 이상하게 보입니다. 고마워요 –

1

임시 테이블을 만들면 spid에서 실행되는 동적 SQL에서 볼 수 있습니다. 동적 SQL에서 테이블을 만들면 테이블 외부에 표시되지 않습니다.

해결 방법이 있습니다. 스텁 테이블을 만들고 동적 SQL에서 변경할 수 있습니다. 약간의 문자열 조작이 필요하지만이 기술을 사용하여 tsqlunit에 대한 동적 데이터 세트를 생성했습니다.

CREATE TABLE #t1 
(
    DummyCol int 
) 

EXEC(N'ALTER TABLE #t1 ADD foo INT') 

EXEC ('insert into #t1(DummyCol, foo) 
VALUES(1,2)') 

EXEC ('ALTER TABLE #t1 DROP COLUMN DummyCol') 

select *from #t1 
+0

열은 미리 알려지지 않았습니까? –

+0

원칙을 증명할 수있는 단지 개념 증명 코드입니다. 열을 파생시키는 데는 여러 가지 방법이 있지만 OP의 경우 열은 '@ cols'로 알려져 있습니다. '@ cols'를 alter 문으로 변환하기 위해서는 어떤 조작이 필요합니다. Damien_The_Unbeliever는이 접근법에 대한보다 완벽한 예를 썼습니다. –

+0

죄송합니다. 당신 말이 맞아요. –