2008-09-23 2 views
5

필자는 열이 존재하는지 확인한 후 열을 삭제하는 (겉으로보기에) 간단한 SQL 미리보기를 작성했습니다.
문제 : 열이 없으면 안에 코드가 있습니다. IF 절은 열을 찾을 수 없다고 불평합니다! 음, doh, 이것이 바로 IF 절 안에있는 이유입니다!
제 질문은 왜 실행해서는 안되는 코드가 오류를 일으키는 것입니까?T-SQL 블록이 실행되지 않아도 오류가 발생하는 이유는 무엇입니까?

여기에 코드 조각입니다 :

IF exists (select * from syscolumns 
    WHERE id=object_id('Table_MD') and name='timeout') 
BEGIN 
    ALTER TABLE [dbo].[Table_MD] 
     DROP COLUMN timeout 
END 
GO 

... 그리고 여기에 오류 발생 : 나는 마이크로 소프트 SQL Server 2005 Express Edition을 사용하고

Error executing SQL script [...]. Invalid column name 'timeout'

.

답변

10
IF exists (select * from syscolumns 
    WHERE id=object_id('Table_MD') and name='timeout') 
BEGIN 
    DECLARE @SQL nvarchar(1000) 
    SET @SQL = N'ALTER TABLE [dbo].[Table_MD] DROP COLUMN timeout' 
    EXEC sp_executesql @SQL 
END 
GO 

이유 : SQL 서버 코드를 컴파일 할 때 (이들이 존재하는 경우) 가 그들이 사용하는 개체를 확인 . 이 검사 절차는 "IF", "WHILE"등의 구문을 무시하고 코드에서 사용 된 모든 객체를 검사합니다. 여기

+0

수정하십시오. sproc이 사용하는 임시 테이블이있을 경우에도이 오류가 발생합니다. – ConcernedOfTunbridgeWells

+0

임시 테이블이 있으면 sproc를 컴파일 할 때 열이 확인됩니다. sproc이 실제로 테이블을 생성하는 곳에서 (예를 들어 select into를 사용하는 경우) sproc을 다시 컴파일하기 전에 테이블을 삭제해야 할 수도 있습니다. – ConcernedOfTunbridgeWells

+0

이것은 아주 좋은 대답입니다 :) –

0

실행해서는 안되지만 Sql Server에서 유효성을 검사합니다. "이겨내"할 수있는 유일한 방법이 동적 SQL 블록을 구축 한 후 선택적으로 실행하는 것이

0

내가이 일을하는 데 방법은 다음 IF 절 내부

, 내가 exec ('ALTER ... DROP ...')

으로 ALTER ... DROP ... 명령을 변경 구문 분석 할 때 SQL 서버 코드에 대한 유효성 검사를 수행 것, 그리고보고 존재하지 않는 열이 어딘가에서 참조되는 경우 (해당 코드가 실행되지 않더라도).
exec(ute) 명령을 사용하면 문제가있는 코드를 문자열로 래핑하고 파서는 불평하지 않으며 코드는 필요한 경우에만 실행됩니다. 여기 수정 된 코드 조각입니다 :

IF exists (select * from syscolumns 
    WHERE id=object_id('Table_MD') and name='timeout') 
BEGIN 
    exec ('ALTER TABLE [dbo].[Table_MD] DROP COLUMN timeout') 
END 
GO 
0

그런데,이 오라클에서 유사한 문제이며, "실행 즉시"절을 사용하여 유사한 문제를 해결.

관련 문제