SQL Server 動態生成數據庫所有表Insert語句


一、 背景

  SQL Server,如果我們需要把數據庫A的所有表數據到數據庫B中,通常我們會怎么做呢?我會使用SSMS的導入導出功能,進行表數據的導入導出,無可厚非,這樣的導入非常簡單和方便;

  但是,當我們的表有上百個,而且有些表是有自增ID的,那么這個時候使用SSMS的話,你需要一個個手動設置(如圖1),你要知道,需要設置上百個的這些選項是件多么痛苦的事情,而且最后很可能會因為外鍵約束導致導入導出失敗。

wpsFA22.tmp

(圖1)

  雖然SSMS在導入導出的最后一步提供了生成SSIS包的功能,但是對於轉移數據的需求來說,還是無法達到我想要的快速、方便。

  自然而然,我想到了INSERT INTO XX SELECT FROM XX WHERE這樣的方式(這種方式的好處就是可以對數據記錄、字段進行控制),但是如何才能快速生成整個數據庫所有表的這些語句呢?

  假如你需要批量生成下面的SQL,我想這篇文章就可以幫到你了:

--[OpinionList]
SET IDENTITY_INSERT [master_new].[dbo].[OpinionList] ON
INSERT INTO [master_new].[dbo].[OpinionList](Id,Batch,LinkId,DB_Names,CreateTime)
SELECT * FROM [DBA_DB].[dbo].[OpinionList]
SET IDENTITY_INSERT [master_new].[dbo].[OpinionList] OFF
GO

 

二、 腳本解釋

(一) 我編寫了一個模板,這個模板你只需要設置@fromdb和@todb的名稱,這樣就會生成從@fromdb導出所有表插入到@todb中的SQL語句,需要注意的是:要選擇@fromdb對應的數據庫執行模板SQL,不然無法生成需要的表和字段。

DECLARE @fromdb VARCHAR(100)
DECLARE @todb VARCHAR(100)
DECLARE @tablename VARCHAR(100)
DECLARE @columnnames NVARCHAR(300)
DECLARE @isidentity NVARCHAR(30)
DECLARE @temsql NVARCHAR(max)
DECLARE @sql NVARCHAR(max)
SET @fromdb = 'master'
SET @todb = 'master_new'

--游標
DECLARE @itemCur CURSOR
SET @itemCur = CURSOR FOR 
    SELECT '['+[name]+']' from sys.tables WHERE type='U' order by name

OPEN @itemCur
FETCH NEXT FROM @itemCur INTO @tablename
WHILE @@FETCH_STATUS=0
BEGIN
    
    SET @sql = ''

    --獲取表字段
    SET @temsql = N'
    BEGIN
    SET @columnnamesOUT =''''
    SELECT @columnnamesOUT = @columnnamesOUT + '','' + name 
    From sys.columns where object_id=OBJECT_ID(''['+@fromdb+'].dbo.'+@tablename+''')
    order by column_id
    SELECT @columnnamesOUT=substring(@columnnamesOUT,2,len(@columnnamesOUT))
    END
    '
    EXEC sp_executesql @temsql,N'@columnnamesOUT NVARCHAR(300) OUTPUT',@columnnamesOUT=@columnnames OUTPUT

    PRINT ('--'+@tablename)

    --判斷是否有自增字段
    SET @temsql = N'
    BEGIN
    SET @isidentityOUT =''''
    SELECT @isidentityOUT = name 
    From sys.columns where object_id=OBJECT_ID(''['+@fromdb+'].dbo.'+@tablename+''')
    and is_identity = 1
    END
    '
    EXEC sp_executesql @temsql,N'@isidentityOUT NVARCHAR(30) OUTPUT',@isidentityOUT=@isidentity OUTPUT

    --IDENTITY_INSERT ON
    IF @isidentity != ''
    BEGIN
        SET @sql = 'SET IDENTITY_INSERT ['+@todb+'].[dbo].['+@tablename+'] ON
'
    END

    --INSERT
    SET @sql = @sql+'INSERT INTO ['+@todb+'].[dbo].['+@tablename+']('+@columnnames+')
SELECT * FROM ['+@fromdb+'].[dbo].['+@tablename+']'

    --IDENTITY_INSERT OFF
    IF @isidentity != ''
    BEGIN
        SET @sql = @sql+'
SET IDENTITY_INSERT ['+@todb+'].[dbo].['+@tablename+'] OFF'
    END

    --返回SQL
    PRINT(@sql)PRINT('GO')+CHAR(13)

    FETCH NEXT FROM @itemCur INTO @tablename
END 

CLOSE @itemCur
DEALLOCATE @itemCur

 

(二) 下面就是返回的生成的部分腳本,模板會自動判斷表是否存在自增字段,如果存在就會生成對應的IDENTITY_INSERT語句。

--spt_values
INSERT INTO [master_new].[dbo].[spt_values](name,number,type,low,high,status)
SELECT * FROM [master].[dbo].[spt_values]
GO

--[OpinionList]
SET IDENTITY_INSERT [master_new].[dbo].[OpinionList] ON
INSERT INTO [master_new].[dbo].[OpinionList](Id,Batch,LinkId,DB_Names,CreateTime)
SELECT * FROM [DBA_DB].[dbo].[OpinionList]
SET IDENTITY_INSERT [master_new].[dbo].[OpinionList] OFF
GO


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM