好的,我开始的上一个帖子是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中的列删除部分工作?
答案 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 + ''')'