2011-01-28 4 views
6

배경 : 주어진 이름의 임시 테이블로 "처리"하는 저장 프로 시저가 있습니다. 이 절차는 임시 테이블의 스키마를 검사 한 다음 스키마에 따라 다른 "물건"을 처리한다는 점에서 일반적입니다. 나는 이것이 이상하다는 것을 이해하지만 대부분의 상황에서 모든 것이 잘 작동하기 때문에 변경하기를 꺼린다. 예외적으로 ...SQL Server가 Temp Table을 아직 존재하지 않는다고 생각하는 이유는 무엇입니까?

임시 테이블에 대해 두 개의 다른 스키마를 만드는 저장 프로 시저가있는 경우 같은 이름. 논리적으로 IF의 어느 분기에 따라 하나의 임시 테이블 만 생성합니다. 문제는 SPROC가 SQL 서버에 의해 확인 될 때이는 IF의 양쪽 평가하고있다처럼 보인다이다

그래서이 SQL 실패 (는 SQL 구문을 확인 않다면 의미가 있습니다.) :

IF (1=1) 
BEGIN 
    CREATE TABLE #test 
    (
     a BIGINT NOT NULL, 
     b BIGINT NOT NULL 
    ) 
END 
ELSE 
BEGIN 
    CREATE TABLE #test 
    (
     a BIGINT NOT NULL, 
     b BIGINT NOT NULL, 
     c BIGINT NOT NULL 
    ) 
END 

--exec SomeProcedureWhichDoesStuffWith#Test 

DROP TABLE #test 
을 다음과 같은 오류와

는 :

Msg 2714, Level 16, State 1, Line 14
There is already an object named '#test' in the database.

IFS의 내부 드롭 테이블의 번호 조합 (이전 또는 이후에 작성 테이블 DDL)는 SQL 검사기를 만족시킬 것으로 보인다.

어떻게하면됩니까? 예를 들어, 구문 검사를 수행하지 않고 sproc을 그대로 사용하도록 SQL에 지시 할 수 있습니까?

답변

6

제한 사항입니다. 동적 SQL은 #tmp가 새로운 세션에서 생성되고 즉시 사라지기 때문에 작동하지 않습니다. 그림과 같이 정확한 조각,이 같은 배치 내 .. 같은

CREATE TABLE #test 
(
    a BIGINT NOT NULL, 
    b BIGINT NOT NULL 
) 

IF not (1=1) 
    ALTER TABLE #test ADD c BIGINT NOT NULL 

이 두 CREATE있을 수 없습니다 # NAME을 수행하지만,이 또한 내가 그나마 때문에 일반적인 형태

IF (1=1) 
BEGIN 
    CREATE TABLE #test 
    (
     a BIGINT NOT NULL, 
     b BIGINT NOT NULL 
    ); 
END 
GO 

IF NOT (1=1) 
BEGIN 
    CREATE TABLE #test 
    (
     a BIGINT NOT NULL, 
     b BIGINT NOT NULL, 
     c BIGINT NOT NULL 
    ) 
END 
0

에서 작동합니다 SQL 2008을 가지고, 그것을 테스트 할 수 없습니다. 그러나 내가 아는 한, 이것은 임시 테이블과 함께 명시 적으로 파서 문제입니다. 같은 단지 논리적 인 GO 문

과 코드 분할이을 제압 일반 테이블

와 함께 잘 작동 할 이상적 : 당신이 당신의 임시 테이블을 작성하기 전에 존재하는 경우이를 삭제, 임시 테이블의 존재를 확인, 마지막으로 당신은 또한 시도하고을 사용할 수 있습니다


이동하여 이동을 발사하는 이동 후 사후 처리를 발사, 다시 임시 테이블의 생성을 수행합니다 이동을 발사 마지막으로 다시 떨어 화재 위의 경우 임시 테이블 대신 테이블 변수를 사용하면 문제가 해결되지 않습니다.

+0

네 감사합니다. 불행히도 그것은 sproc에 테이블을 생성하기 때문에 동일한 배치에 있어야합니다 (그래서 GO가 없습니다). –

0

당신은 항상 "속임수"수 :

DECLARE @SQL VARCHAR(200) 

IF (1=1) 
BEGIN 
    SET @SQL = 'CREATE TABLE #Temp  ' + 
       '(      ' + 
       ' a BIGINT NOT NULL, ' + 
       ' b BIGINT NOT NULL ' + 
       ')      ' 
END 
ELSE 
BEGIN 
    SET @SQL = 'CREATE TABLE #Temp  ' + 
       '(      ' + 
       ' a BIGINT NOT NULL, ' + 
       ' b BIGINT NOT NULL, ' + 
       ' c BIGINT NOT NULL ' + 
       ')      ' 
END 

EXEC SP_EXECUTESQL @SQL 
+0

그것은 즉시 범위를 벗어나 외부 스크립트에서 사용할 수 없으므로 작동하지 않습니다. 전역 임시 테이블이거나 임시 테이블의 모든 사용법이 동적 SQL에 있어야합니다. –

2

대신 #test의 정규화 된 이름을 사용합니다. 예 :

[tempdb].[dbo].[temptable] 

이 작은 트릭을 여기서 알게되었습니다. Insert result of executing dynamic query into a table.

Intellisense는 불만을 표시하지만 여전히 저장 프로 시저를 만들거나 변경할 수 있습니다.그것으로 완료되면

, 드롭해야합니다 : 정보에 대한

DROP TABLE [tempdb].[dbo].[temptable] 
관련 문제