有没有一种方法可以完全通过T-SQL从现有表中生成创建脚本(即不使用SMO,因为T-SQL无法访问SMO)。假设一个存储过程接收一个表名并返回一个包含给定表的创建脚本的字符串?
现在,让我描述一下我所面临的情况,因为可能有不同的方法来解决这个问题。我有一个包含数十个数据库的实例。这些数据库都具有相同的架构,所有相同的表,索引,等等。它们是作为第三方软件安装的一部分创建的。我需要一种与他们合作的方式,以便可以以临时方式汇总来自他们的数据。dba.se的好人已经在这里为我提供了帮助。如何在其他数据库中创建触发器?
当前,我需要找到一种从所有数据库的表中进行选择的方法。我已将所有数据库名称记录到一个名为的表中,Databasees
并且编写了以下脚本以对所有数据库名称执行select语句:
IF OBJECT_ID('tempdb..#tmp') IS NOT NULL
DROP TABLE #tmp
select * into #tmp from Database1.dbo.Table1 where 1=0
DECLARE @statement nvarchar(max) =
N'insert into #tmp select * from Table1 where Column1=0 and Cloumn2 =1'
DECLARE @LastDatabaseID INT
SET @LastDatabaseID = 0
DECLARE @DatabaseNameToHandle varchar(60)
DECLARE @DatabaseIDToHandle int
SELECT TOP 1 @DatabaseNameToHandle = Name,
@DatabaseIDToHandle = Database_Ref_No
FROM Databasees
WHERE Database_Ref_No > @LastDatabaseID
ORDER BY Database_Ref_No
WHILE @DatabaseIDToHandle IS NOT NULL
BEGIN
DECLARE @sql NVARCHAR(MAX) = QUOTENAME(@DatabaseNameToHandle) + '.dbo.sp_executesql'
EXEC @sql @statement
SET @LastDatabaseID = @DatabaseIDToHandle
SET @DatabaseIDToHandle = NULL
SELECT TOP 1 @DatabaseNameToHandle = Name,
@DatabaseIDToHandle = Database_Ref_No
FROM Databasees
WHERE Database_Ref_No > @LastDatabaseID
ORDER BY Database_Ref_No
END
select * from #tmp
DROP TABLE #tmp
但是,上面的脚本失败,并显示以下消息:
仅当使用列列表且IDENTITY_INSERT为ON时,才能为表'#tmp'中的identity列指定一个显式值。
添加:
SET IDENTITY_INSERT #tmp ON
这无济于事,因为我无法指定列列表并使它保持通用。
在SQL中,无法关闭给定表上的标识。您只能删除一列并添加一列,这显然会改变列的顺序。而且,如果列顺序更改,则需要再次指定列列表,这取决于查询的表。
因此,我在考虑是否可以在T-SQL代码中获得创建表脚本,我可以使用字符串操作表达式对其进行操作以删除标识列,并在结果集中添加一列数据库名称。
谁能想到一个相对简单的方法来实现我想要的?