2016-11-01 8 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 + ''')' 
関連する問題