2016-11-01 5 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 

Так как же я могу получить часть удаления столбца моей работы?

+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 + ''')' 

 Смежные вопросы

  • Нет связанных вопросов^_^