跟进 - 档案存储程序

时间:2016-11-01 14:57:46

标签: sql-server dynamic-sql

好的,我开始的上一个帖子是Archival stored procedures,但这是一个后续问题。我所拥有的是一个工作存储过程,它可以生成活动数据库的精确副本,但是当我想删除上个月的旧列时,该过程会在那里出现错误:

  

Msg 102,Level 15,State 1,Line 3
  ' 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 TABLE_NAME=@tablename and column_name not in (select column_name from INFORMATION_SCHEMA.COLUMNS 
            where TABLE_NAME=@tablearchive))
    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中的列删除部分工作?

1 个答案:

答案 0 :(得分: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 + ''')'