2013-07-31 2 views
0

나는 테이블의 내용을 통해 해당 루프를 생성하는 코드를 찾아 내고 여전히 유효한 열인지 확인하고 더 이상 유효하지 않은 열을 모두 삭제합니다. 어떤 이유로 EXECUTE에 대한 테이블에서 열을 삭제

declare @counter int 
declare @col_count int 
declare @col_name char(100) 
declare @temp_sql char(100) 
set @counter = 0 

SELECT @col_count = COUNT(*) from sys.columns 
where Object_ID = Object_ID(N'test') 
AND name <> 'pk_test' 

while @counter < @col_count 
begin 
    with CTE as (
    select name, row_number() over (order by column_id) as ColNo 
    from sys.columns where object_id = object_id('test') AND name <> 'pk_test' 
) 
    select @col_name = name from CTE where ColNo = ((@counter) + 1) 

    SET @temp_sql = 'ALTER TABLE test DROP column ' + @col_name + ';' 
    EXECUTE (@temp_sql); 

    set @counter = @counter + 1 
end 

다른 모든 호출을 건너 뛸 코드의 원인,하지만 난 꺼내 경우, 모든 유효한 드롭 문을 표시합니다 코멘트와 함께 실행하고 인쇄 던져된다. 나는이 일을 시도

:

SET @temp_sql = @temp_swl + 'ALTER TABLE test DROP column ' + @col_name 
enter code here 

나는 한 번에 모든 ALTER 테이블을 결합하는 시도했지만 작동하지 않는 것 같습니다.

나는 작은 것을 놓치고 있다고 느낍니다.

+0

새 테이블에 유효한 열을 밀어 넣은 다음 이전 테이블을 삭제하고 새 테이블의 이름을 바꾸는 것이 궁금합니다. – brian

+1

@brian 그것은 많은 양의 데이터 일 수 있으며, 보관중인 열을 가리키는 많은 외래 키가있을 수 있습니다. –

+0

솔직히, 나는 생각하지 않았기 때문에 :-), 가능하다면 데이터를 유지하려고합니다. dev가 테이블을 완전히 삭제하려고하거나, 단순히 "업데이트"하려는 경우 "재설정"플래그가 있습니다. 그것. 나는 아직도 놀고있어 모든 것을 마무리하고있다. 나는 이것을 염두에 둘 것이다! – Krum110487

답변

1

여기에 커서 (while 루프의 또 다른 이름)가 필요없고 더 이상 건너 뛰지 않아도되는 더 간단한 방법이 있습니다. "유효하지 않음"은 "pk_test"이 아님을 전제로합니다. "유효하지 않음"이 다른 것을 의미 할 경우 명확히하십시오. 물론 테이블에 pk_test 열이 먼저 있는지 확인해야합니다. 그렇지 않으면 마지막 ALTER이 실패합니다. 코드에서 현재이를 확인하지 않습니다.

+0

정말 T-SQL을 배울 필요가 있습니다. 이것은 대단히 도움이됩니다. 지금해야 할 일은 테이블의 현재 열 목록을 생성하는 것입니다. 목록에없는 열을 모두 제거합니다! 큰! 또한 단순히 AND 대신 (name <> 'column 1 or name <>'column2 'OR name <>'column3 ') 항목 목록을 만드는 더 쉬운 방법입니다. 나는 단순히 "c"변수에 대해 생성 할 수 있다고 가정합니다. – Krum110487

+0

@ Krum110487 SQL Server의 버전은 무엇입니까? 2008 이상인 경우 테이블 반환 매개 변수에 대해 존재할 수 없습니다. 이전에 수동으로 #temp 테이블을 수동으로 채우고이를 수행 할 수는 없습니다. –

2

alter table 문을 사용하여 한 행 (즉 열)을 제거하는 경우를 제외하고는 항상 카운터로 테이블을 다시 생성합니다.

대신 테이블을 먼저 생성 한 다음 루프를 반복하십시오. 이와

while @counter < @col_count 
begin 
    with CTE as (
    select name, row_number() over (order by column_id) as ColNo 
    from sys.columns where object_id = object_id('test') AND name <> 'pk_test' 
) 
    select @col_name = name from CTE where ColNo = ((@counter) + 1) 

    SET @temp_sql = 'ALTER TABLE test DROP column ' + @col_name + ';' 
    EXECUTE (@temp_sql); 

    set @counter = @counter + 1 
end 

: 나는 당신이하고있는 일에 대해 언급하지 않을거야

declare @columns table (colnum int not null identity(1, 1), colname varchar(255)); 

insert into @columns(colname) 
    select name 
    from sys.columns 
    where object_id = object_id('test') AND name <> 'pk_test'; 

set @col_count = max(colnum) from @columns; 

while @counter < @col_count 
begin 

    select @col_name = name from @columns where ColNo = ((@counter) + 1); 

    SET @temp_sql = 'ALTER TABLE test DROP column ' + @col_name + ';' 
    EXECUTE (@temp_sql); 

    set @counter = @counter + 1; 
end; 

을하지만,이 목록을 미리 계산함으로써 "생략"문제를 해결해야한다 그래서,이 교체 열. 그렇게하면 목록에 alter table 문이 적용되지 않습니다.

+0

아,이 말이 맞습니다! 이 코드의 핵심은 데이터베이스 생성을위한 것입니다. 기본적으로 dev에 대해서만, 프로덕션 스크립트가 아니라 내 인생을 더 쉽게 만들어주는 것입니다! 감사합니다! – Krum110487