2012-09-21 2 views
19

SQL Server에 대한이 코드의 문제점을 누구에게 알 수 있습니까? 나는이 프로그램을 실행할 때열 생성 후 SQL Server 업데이트의 열 이름이 잘못되었습니다.

IF NOT EXISTS(SELECT * 
       FROM sys.columns 
       WHERE Name = 'OPT_LOCK' 
        AND object_ID = Object_id('REP_DSGN_SEC_GRP_LNK')) 
    BEGIN 
     ALTER TABLE REP_DSGN_SEC_GRP_LNK 
     ADD OPT_LOCK NUMERIC(10, 0) 

     UPDATE REP_DSGN_SEC_GRP_LNK 
     SET OPT_LOCK = 0 

     ALTER TABLE REP_DSGN_SEC_GRP_LNK 
     ALTER COLUMN OPT_LOCK NUMERIC(10, 0) NOT NULL 
    END; 

, 내가 얻을 :

메시지 207, 수준 16, 상태 1, 줄 3
잘못된 열 이름 'OPT_LOCK'.

업데이트 명령.

감사합니다.

답변

33

이 경우 열을 NOT NULL으로 추가하고 하나의 명령문에 기존 행의 값을 설정하여이 문제를 피할 수 있습니다. as per my answer here.

보다 일반적으로 문제는 구문 분석/컴파일 문제입니다. SQL Server는 모든 문을 실행하기 전에 배치의 모든 문을 컴파일하려고합니다.

모든 명령문에 존재하지 않는 테이블을 참조하는 명령문은 지연된 컴파일의 대상이됩니다. 테이블이 이미 존재하면 존재하지 않는 열을 참조하면 오류가 발생합니다. 가장 좋은 방법은 DML과 다른 배치에서 DDL을 수행하는 것입니다.

문이 기존 테이블의 존재하지 않는 열과 존재하지 않는 테이블을 참조하는 경우 컴파일이 지연되기 전에 오류가 발생하거나 그렇지 않을 수 있습니다.

하면 (예를 들어, 클라이언트 도구에 배치 GO 분리기를 사용하여) 분리 된 배치로 제출하거나 또는 EXECEXEC sp_executesql을 사용하여 개별적으로 컴파일 된 하위 범위에서 수행 할 수 있습니다.

첫 번째 방법은 코드를 리팩터링하여 IF ...이 범위를 확장 할 수 없도록하는 것입니다.

당신의 내용
IF NOT EXISTS(SELECT * 
       FROM sys.columns 
       WHERE Name = 'OPT_LOCK' 
        AND object_ID = Object_id('REP_DSGN_SEC_GRP_LNK')) 
    BEGIN 
     ALTER TABLE REP_DSGN_SEC_GRP_LNK 
     ADD OPT_LOCK NUMERIC(10, 0) 

     EXEC('UPDATE REP_DSGN_SEC_GRP_LNK SET OPT_LOCK = 0'); 

     ALTER TABLE REP_DSGN_SEC_GRP_LNK 
     ALTER COLUMN OPT_LOCK NUMERIC(10, 0) NOT NULL 
    END; 
+1

EXEC에 접근했습니다. 감사! – feradz

+0

이것은 지난 몇 년 동안 사용해 왔던 접근 방식이며 새로운 열을 추가하고 데이터를 채울 때마다 우리가이 어색한 동적 SQL 경로를 사용해야한다는 것을 항상 놀라게합니다. –

0

, 당신은 COL_LENGTH 기능을 가진 IF NOT EXISTS를 교체 할 수 있습니다. 열은 후 발견이 열 예의 데이터 타입의 범위를 반환하는 경우는 두 개의 매개 변수,

  1. 표 이름과

를 검색

  • 열합니다 : Int (4 바이트), 찾을 수없는 경우 NULL을 반환합니다.

    따라서 다음과 같이 사용할 수 있으며 3 개의 명령문을 하나로 결합 할 수 있습니다.

    IF (SELECT COL_LENGTH('REP_DSGN_SEC_GRP_LNK','OPT_LOCK')) IS NULL 
    
    BEGIN 
    
        ALTER TABLE REP_DSGN_SEC_GRP_LNK 
        ADD OPT_LOCK NUMERIC(10, 0) NOT NULL DEFAULT 0 
    
    END; 
    

    더 간단하게 만듭니다.