识别数据库中的空白表,并将另一个表中的数据插入到不同的数据库中

时间:2013-07-19 11:12:45

标签: sql sql-server sql-server-2008 tsql

实际场景:我有一个重复的数据库,想要知道哪些表数据尚未从原始数据库移动。然后我想从Original填充Duplicate数据库表。

  

我完成了我的部分解决方案(即查找空表),编写了以下脚本:

SELECT
    DBDupl.[dbo].sysobjects.Name, DBDupl.[dbo].sysindexes.Rows FROM
    DBDupl.[dbo].sysobjects
    INNER JOIN DBDupl.[dbo].sysindexes
    ON DBDupl.[dbo].sysobjects.id = DCT_SOURCE_QA.[dbo].sysindexes.id WHERE
    type = 'U'
    AND DBDupl.[dbo].sysindexes.IndId < 2 and rows= '0'
     EXCEPT

SELECT
    DBOrig.[dbo].sysobjects.Name, DBOrig.[dbo].sysindexes.Rows FROM
    DBOrig.[dbo].sysobjects
    INNER JOIN DBOrig.[dbo].sysindexes

    ON DBOrig.[dbo].sysobjects.id = DBOrig.[dbo].sysindexes.id WHERE
    type = 'U'
    AND DBOrig.[dbo].sysindexes.IndId < 2 and rows= '0'

现在我想填充空表中的数据。有没有一个查询来做这两件事,即(1)找出要填充的表和(2)。将数据从DBOrig填充到DBDupl。我已经使用上面的脚本实现了(1)并且不想手动插入数据。

2 个答案:

答案 0 :(得分:0)

您想要数据库的精确副本吗?为什么不是主要备份和具有不同名称的还原?

如果不可能,您可以使用SSIS移动数据或类似:

insert into destDB.dbo.mytable
select * sourcedb.dbo.mytable

您可以使用脚本遍历空表并运行一些动态SQL来执行上面的命令

答案 1 :(得分:0)

你能不能:

1)获取表列表

2)对于每个表,从一个数据库插入到另一个数据库

仅供参考-如果您需要比较数据库,Visual Studio可以进行模式/数据比较,并且是免费的

这是一个示例脚本。假定表结构相同。 您可以使用print生成脚本或执行命令(已注释掉)


SET NOCOUNT ON 


DECLARE
    @objectName nvarchar(256)
    ,@sql nvarchar(max)
    ,@db1 nvarchar(100) = 'DB_1'
    ,@db2 nvarchar(100) = 'DB_2'

DROP TABLE IF EXISTS #EmptyTables


;WITH c_EmptyTables AS (
    SELECT t.object_id
        ,s.Name AS SchemaName
        ,t.Name AS TableName
        ,p.rows AS RowCounts
        ,FullName = CONCAT (
            QUOTENAME(s.name)
            ,'.'
            ,QUOTENAME(t.name)
            )
        ,CAST(ROUND((SUM(a.used_pages) / 128.00), 2) AS NUMERIC(36, 2)) AS Used_MB
        ,CAST(ROUND((SUM(a.total_pages) - SUM(a.used_pages)) / 128.00, 2) AS NUMERIC(36, 2)) AS Unused_MB
        ,CAST(ROUND((SUM(a.total_pages) / 128.00), 2) AS NUMERIC(36, 2)) AS Total_MB
    FROM sys.tables t
    INNER JOIN sys.indexes i ON t.OBJECT_ID = i.object_id
    INNER JOIN sys.partitions p ON i.object_id = p.OBJECT_ID
        AND i.index_id = p.index_id
    INNER JOIN sys.allocation_units a ON p.partition_id = a.container_id
    INNER JOIN sys.schemas s ON t.schema_id = s.schema_id
    WHERE ISNULL(p.rows, 0) = 0
    GROUP BY t.Name
        ,s.Name
        ,p.Rows
        ,t.object_id
)

SELECT *
INTO #EmptyTables
FROM c_EmptyTables

DECLARE cur CURSOR LOCAL FAST_FORWARD
FOR
    SELECT FullName
    FROM #EmptyTables t

OPEN cur 

FETCH NEXT 
FROM cur
INTO 
    @objectName

WHILE @@FETCH_STATUS = 0
BEGIN
    SET @sql = 'INSERT INTO ' + @db1 + '.' + @objectName + CHAR(10)
                + 'SELECT * FROM ' + @db2 + '.' + @objectName
                + CHAR(10) + 'GO' + CHAR(10)

    PRINT(@sql)

    BEGIN TRY
        BEGIN TRANSACTION

            --EXEC(@sql)

        COMMIT TRANSACTION;
    END TRY
    BEGIN CATCH

        IF (@@TRANCOUNT > 0)
            ROLLBACK TRANSACTION;

        PRINT CHAR(10) + '*** UPDATE FAILED FOR ***';
        PRINT CHAR(10) + @sql
        PRINT CHAR(10)

        SELECT
             ERROR_NUMBER() AS ErrorNumber
            ,ERROR_SEVERITY() AS ErrorSeverity
            ,ERROR_STATE() AS ErrorState
            ,ERROR_PROCEDURE() AS ErrorProcedure
            ,ERROR_LINE() AS ErrorLine
            ,ERROR_MESSAGE() AS ErrorMessage;
    END CATCH


    FETCH NEXT 
    FROM cur
    INTO 
        @objectName
END
CLOSE cur
DEALLOCATE cur