2016-11-01 4 views
0

좋아, 제가 시작한 이전 스레드는 Archival stored procedures이었습니다. 그러나 이것에 대한 후속 질문입니다. 내가 가지고있는 것은 내가 이전 달에서 이전 열을 제거 할 그러나 때, 활성 데이터베이스의 정확한 복사본을 만드는 작업 저장 프로 시저입니다, 절차는 오류가 바로 불면 : 여기후속 조치 - 보관 저장 프로 시저

Msg 102, Level 15, State 1, Line 3
Incorrect syntax near 'D201609__'.

전체 프로 시저의 코드입니다 :

declare @tablename varchar(500) 
declare @sql varchar(5000) 
declare @idname varchar(50) 
declare @tablearchive varchar(500) 
declare @lastmonth nvarchar(MAX) 

SET @lastmonth = 'D' + cast(year(getdate()) as char(4)) + right('0' + cast(month(getdate())-1 as varchar), 2) + '__' 
--Select all the tables which you want to make in archive 

declare tableCursor cursor FAST_FORWARD FOR 
    SELECT table_name 
    FROM INFORMATION_SCHEMA.TABLES 
    WHERE table_name = 'CVECountsByDate' 

--Put your condition, if you want to filter the tables 
--like '%TRN_%' and charindex('Archive',table_name) = 0 and charindex('ErrorLog',table_name) = 0 
--Open the cursor and iterate till end 
OPEN tableCursor 
FETCH NEXT FROM tableCursor INTO @tablename  

WHILE @@FETCH_STATUS = 0 
BEGIN 
    set @tablearchive = @tablename+'_Archive' 

    --check for the table exists, not, create it 
    IF not EXISTS (SELECT 1 FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_TYPE='BASE TABLE' AND TABLE_NAME= @tablearchive) 
    BEGIN 
     SET @sql = 'select * into ' + @tablearchive +' from '+ @tablename +' where 1=2' 
     EXEC(@sql) 
    END 

    --check the structure is same, if not, create it 
    IF exists (select column_name from 
      INFORMATION_SCHEMA.COLUMNS where [email protected] and column_name not in (select column_name from INFORMATION_SCHEMA.COLUMNS 
      where [email protected])) 
    BEGIN 
     SET @sql = 'drop table ' + @tablearchive 
     EXEC(@sql) 

     SET @sql = 'select * into ' + @tablearchive +' from '+ @tablename +' where 1=2' 
     EXEC(@sql) 
    END 

    --Check if the table contains, identify column,if yes, then it should be handled in different way 
    --You cannot remove the identity column property through T-SQL 
    --Since the structure of both tables are same, the insert fails, as it cannot insert the identity column 
    --value in the archive table 
    IF EXISTS(SELECT *  FROM information_schema.tables  WHERE table_name = @tablename AND OBJECTPROPERTY(OBJECT_ID(TABLE_NAME), 
      'TableHasIdentity') != 0) 
    BEGIN 
     --Select the identity column name automatically    
     select @idname = column_name 
     from information_schema.columns 
     where columnproperty(object_id(table_name), column_name, 'isidentity') = 1 
      and table_name = @tablearchive 

     --Remove the column 
     SET @sql = 'ALTER TABLE ' + @tablearchive + ' DROP COLUMN ' + @idname 
     EXEC(@sql) 

     --Create the column name again (not as identity) 
     --archive table does require identity column 
     SET @sql = 'ALTER TABLE ' + @tablearchive + ' ADD ' + @idname+ ' INT' 
     EXEC(@sql) 
    END 

    SET @sql = 'insert into ' + @tablearchive +' select * from '+ @tablename 
    EXEC(@sql) 

    FETCH NEXT FROM tableCursor INTO @tablename 

    declare @PrevMonth nvarchar(MAX) = 'D' + cast(year(getdate()) as char(4)) + right('0' + cast(month(getdate())-1 as varchar), 2) + '__' 
    DECLARE @DynSql nvarchar(MAX) = 'ALTER TABLE ' + @tablename + ' DROP COLUMNS IF EXISTS 
    (SELECT COLUMN_NAME Columns FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = ' + @tablename + ' 
AND COLUMN_NAME LIKE ' + @PrevMonth + '' 

    SELECT (@DynSql) 
    EXEC(@DynSql) 
END 

CLOSE tableCursor 
DEALLOCATE tableCursor 

정확히 어떻게하면 내 proc의 열 제거 부분이 작동합니까? 분명히 내가 방법을 응시

+3

난 당신이 당신이 매달 스키마와 엉망이 그나마 해결책에 당신의 접근 방식을 재고해야한다고 생각. 그것은 나에게 나쁜 디자인처럼 보인다. –

+0

@ RicardoC에 동의합니다. 매월 스키마를 변경해야하는 경우 디자인에 끔찍한 오류가 있다는 것을 분명히 알 수 있습니다. 데이터베이스는 데이터를 보유하도록 설계되었으며 항상 꼭두각시 인 것처럼 조작되지 않습니다. –

+0

그 절차는 내가 다른 누군가에게서 얻은 것입니다. 그래서이 모든 열을 메인 테이블에 남길 것을 권하고 있습니까? 3000 이상 매일 매일 수치 기록을 가져오고 있다는 것을 알고 계십니까? 내가 당신에게 말할 때 나를 믿어 라, 나는 아주 신중하게 행별로 데이터를 두는 것을 고려했다. 그러나 데이터베이스 테이블은 매우 빠르게 커지게 될 것이다. 내 관심사는 CVE_Id 번호로 참조한 다음 날짜 열에 카운트를 배치하는 것입니다. 당신이 다른 스키마 아이디어를 가지고 있지 않으면. – bbcompent1

답변

0

내 쿼리가 너무 오래 읽기 :이 실제로이 같은 출력을 가져야한다

ALTER TABLE CVECountsByDate DROP COLUMNS IF EXISTS (SELECT COLUMN_NAME 
Columns FROM INFORMATION_SCHEMA.COLUMNS 
WHERE TABLE_NAME = CVECountsByDate AND COLUMN_NAME LIKE 'D201609__' 

:

ALTER TABLE CVECountsByDate DROP COLUMNS IF EXISTS (SELECT COLUMN_NAME 
Columns FROM INFORMATION_SCHEMA.COLUMNS 
WHERE TABLE_NAME = 'CVECountsByDate' AND COLUMN_NAME LIKE 'D201609__' 

나는 따옴표 테이블 이름을 둘러싸는 것을 잊었다. 그리고 예, 저는 이마 중간에 빨간 손 프린트가있어서 저를 떠올리게합니다. 다음과 같이

그래서 쿼리 자체 읽

DECLARE @DynSql nvarchar(MAX) = 'ALTER TABLE CVECountsByDate DROP 
    COLUMNS IF EXISTS (SELECT COLUMN_NAME Columns FROM 
    INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = '''CVECountsByDate''' AND 
    COLUMN_NAME LIKE ''' + @PrevYear + ''')'