2011-02-28 3 views
21

SQL Server 2005/2008을 사용하고 있습니다. 아직 테이블이 존재하지 않으면 테이블에 열을 추가해야합니다. 이것은 주어진 데이터베이스의 모든 테이블에 적용됩니다. 나는 가까이에 있기를 바랐지만이 솔루션에 문제가 있습니다.열이 모든 테이블에 없으면 추가 하시겠습니까?

어떻게이 작업을 수행 할 수 있습니까?

EXEC sp_MSforeachtable ' 
    declare @tblname varchar(255); 
    SET @tblname = PARSENAME("?",1); 

    if not exists (select column_name from INFORMATION_SCHEMA.columns 
        where table_name = @tblname and column_name = ''CreatedOn'') 
    begin 
     ALTER TABLE @tblname ADD CreatedOn datetime NOT NULL DEFAULT getdate(); 
    end 
' 

하지만 오류를 얻을 :

여기에 내가 가진 무엇

오류 102 : 근처의 구문이 잘못되었습니다 '@tblname을'. 'CreatedOn'근처의 구문이 잘못되었습니다. '@tblname'근처의 구문이 잘못되었습니다. 'CreatedOn'근처의 구문이 잘못되었습니다. ... 등등. 각 테이블에 대해.

+0

가능한 중복 http://stackoverflow.com/questions/1779743/adding-a-column- to-all-user-tables-in-t-sql – JAiro

+0

@JAiro : 분명히 관련 링크이지만, "존재하지 않는다면"규칙은 중요하며 좀 더 복잡하게 만듭니다. –

+0

ok 이렇게하면 정보를 완료 할 수 있습니다. http://stackoverflow.com/questions/133031/how-to-check-if-column-exists-in-sql-server-table – JAiro

답변

23

. 게다가 이름을 부분으로 splint하고 스키마를 무시하면 버그가 발생할 수 있습니다. '?'당신은 단지 SQL 배치 매개 변수에 ''대체를 사용하고 MSforeachtable 교체에 의존한다 :의

EXEC sp_MSforeachtable ' 
if not exists (select * from sys.columns 
       where object_id = object_id(''?'') 
       and name = ''CreatedOn'') 
begin 
    ALTER TABLE ? ADD CreatedOn datetime NOT NULL DEFAULT getdate(); 
end'; 
+0

sp_msforeachtable은 지원되지 않는 저장 프로 시저이므로 프로덕션 코드에 사용하면 안됩니다. 몇 줄의 코드를 추가하지만 sys.schemas 및 sys.tables에서 select로 정의 된 ** 커서 **를 사용하는 경우 T-SQL의 문서화 된 부분을 사용하고 있습니다. 모두 또는에 영향을 줄 수 있습니다. 테이블의 일부는 단순히 WHERE 표현식을 변경하여 성능이 동일합니다. ** quotename ** ** 함수를 사용하면 더 적은 수의 한정어를 처리 할 수 ​​있습니다. 마지막으로 스키마/테이블 이름을 원하는대로 (예 : 로그 용) 사용할 수 있습니다. –

+0

@PhilHelmer 예제와 함께 훌륭한 답변을 얻었을 것입니다. – xr280xr

4

약간의 동적 SQL을 사용해야합니다. 이 작업을해야합니다 : 어쩌면이 같은

EXEC sp_MSforeachtable ' 
    declare @tblname varchar(255); 
    SET @tblname = PARSENAME("?",1); 
    declare @sql nvarchar(1000); 

    if not exists (select column_name from INFORMATION_SCHEMA.columns 
        where table_name = @tblname and column_name = ''CreatedOn'') 
    begin 
     set @sql = N''ALTER TABLE '' + @tblname + N'' ADD CreatedOn datetime NOT NULL DEFAULT getdate();'' 
     exec sp_executesql @sql 
    end 
' 
+0

다른 스키마에서 같은 이름을 가진 두 개의 테이블은 어떻습니까? 'foo.t'와'bar.t' ... –

+0

@ Remus : 예, OP가 스키마를 사용하고 있다면 문제가됩니다. 당신의 대답에 +1하십시오. –

0

:

EXEC sp_MSforeachtable ' 
    declare @tblname varchar(255); 
    SET @tblname = PARSENAME("?",1); 

    if not exists (select column_name from INFORMATION_SCHEMA.columns 
        where table_name = @tblname and column_name = ''CreatedOn'') 
    begin 
     ALTER TABLE [?] ADD CreatedOn datetime NOT NULL DEFAULT getdate(); 
    end 
' 

를?

심지어 같은

: 당신은 DDL에서, @tablename 같은 변수를 사용할 수 없습니다

EXEC sp_MSforeachtable ' 
    if not exists (select column_name from INFORMATION_SCHEMA.columns 
        where table_name = ''?'' and column_name = ''CreatedOn'') 
    begin 
     ALTER TABLE [?] ADD CreatedOn datetime NOT NULL DEFAULT getdate(); 
    end 
' 
+2

-1은 게시하기 전에 분명히 테스트하지 않았습니다. '[?]'는 벌써 괄호로 묶은 이름 주위에 괄호를 추가하여'[[schemaname]. [tablename]]'이 부정확합니다. –

+0

@Remus Rusanu : 나는 이것을 테스트했다 :'sp_MSforeachtable 'EXEC sp_help?; EXEC sp_columns? ''. 구문 오류가 발생했습니다. 나는 그것을 'sp_MSforeachtable'으로 변경했다. EXEC sp_help [?]; EXEC sp_columns [?] '', 작동했습니다 (SQL Server 2008 R2). –

+0

... 아직 OP'ALTER TABLE [?]'을 테스트하지 않았습니다. 'sp_help [foo]. [bar]'는 유효하지 않은 문법이기 때문에'?'대체는''sp_help''와''sp_columns'' 모두 저장 프로 시저입니다. 그러나'sp_help [[foo]]. [bar]]]'구문은 올바른 구문이며 매개 변수 처리 방법으로 인해 실제로 작동합니다. 'ALTER TABLE [[foo]]. [bar]]]'하지만 작동하지 않습니다. 긴 이야기를 너무 짧게 유지하기 : 게시 한 코드는 기본적인 구문 검사를 통과하지 못하며, 이는 누구든지 확인할 수 있습니다. –

관련 문제