我的数据库中有大量表,可以将它们称为Table1,Table2,Table3等,我需要对其进行设置以进行合并复制,这意味着SQL Server将在每个表中创建一个新的列(rowguid)。
这对于我的前端来说是有问题的(不能更改),所以我现在的想法是为每个表创建一个View,并删除rowguid列,并将其置于自己的模式下。
由于表的数量众多,并且每个表中的列数量很多,因此不容易手动完成,因此现在我正尝试为此编写一些SQL代码。没有成功,我必须说。
我需要的是一个递归代码,该递归代码可为每个表创建一个新视图(与该表具有相同的名称,但使用的是新的架构),但是省略了每个表中的rowguid列。
我已经找到了如何在不必明确知道列名的情况下删除rowguid列的方法(它们在表之间是不同的。
SELECT * INTO #TemporaryTable FROM [dbo].[Table1]
ALTER TABLE #TemporaryTable DROP COLUMN rowguid
SELECT * FROM #TemporaryTable
DROP TABLE #TemporaryTable
但是如何将其与CREATE VIEW结合使用(据我所知只能有一个SELECT),然后使其遍历数据库中的所有表,这远远超出了我的能力。
一种解决方法是使用动态SQL。但是,CREATE VIEW
必须是批处理中的唯一语句,这意味着如果要为每个表创建一个语句,则需要使用动态动态SQL(是的,我说过),或者使用CURSOR
。前者的性能更高,但后者更易于阅读(和书写)。如果这是一个过程,那么我对性能的担心就不那么多了,所以我将沿着CURSOR
路线走。
CREATE SCHEMA vw; --Create a schema for the views
GO
DECLARE Tables CURSOR FORWARD_ONLY
FOR
SELECT s.[name] AS SchemaName,
t.[name] AS TableName
FROM sys.schemas s
JOIN sys.tables t ON s.schema_id = t.schema_id
WHERE EXISTS (SELECT 1
FROM sys.columns c
WHERE c.object_id = t.object_id
AND c.[name] = N'rowguid'); --Incase you have tables without this, as I assume you don't need views of those
DECLARE @SchemaName sysname,
@TableName sysname,
@SQL nvarchar(MAX),
@CRLF nchar(2) = NCHAR(13) + NCHAR(10);
OPEN Tables;
FETCH NEXT FROM Tables
INTO @SchemaName, @TableName;
WHILE @@FETCH_STATUS = 0
BEGIN
PRINT N'Creating View for object ' + QUOTENAME(@SchemaName) + N'.' + QUOTENAME(@TableName) + N'.';
--Create the dynamic statement
SET @SQL = N'CREATE VIEW vw.' + QUOTENAME(@TableName) + N' AS' + @CRLF + @CRLF +
N' SELECT ' + STUFF((SELECT N',' + @CRLF +
N' ' + QUOTENAME(C.[name])
FROM sys.columns c
JOIN sys.tables t ON c.object_id = t.object_id
JOIN sys.schemas s ON t.schema_id = s.schema_id
WHERE t.[name] = @TableName
AND s.name = @SchemaName
AND c.[name] != N'rowguid'
ORDER BY c.column_id ASC
FOR XML PATH(N''),TYPE).value('.','nvarchar(MAX)'),1,14,N'') + @CRLF +
N' FROM ' + QUOTENAME(@SchemaName) + N'.' + QUOTENAME(@TableName) + N';'
PRINT @SQL; --Incase you need to the code run for debugging
--Create the View
EXEC sp_executesql @SQL;
--Get next object
FETCH NEXT FROM Tables
INTO @SchemaName, @TableName;
END;
CLOSE Tables;
DEALLOCATE Tables;