SQLSERVER 內建的資料匯入工具有兩點不好:
1. 資料庫複寫,會複製所有表的所有資料,有的大表沒有必要導,不好控制
2. 資料匯入,當表中有IDENTITY限制時,只能一個一個表去設定取消,匯入後再設定回去
今天寫了一段SQL,來執行部分表的資料匯入
用到了一些知識點:
1. 建立連結的伺服器
2. 設定IDENTITY列的可插入屬性
3. 帶參數的遊標
建立連結的伺服器
EXEC sp_addlinkedserver
@server='DBVIP',
@srvproduct='',
@provider='SQLOLEDB',
@datasrc='58.1.2.3'
EXEC sp_addlinkedsrvlogin
'DBVIP',
'false',
NULL,
'sa',
'sapwd'
// 先產生來來源資料庫的指令碼,在目標伺服器上建立新的資料庫,這是目標資料庫
的結構和來來源資料庫是一樣的
// 先建立一個暫存資料表,將包含IDENTITY屬性列的表的名稱匯入導暫存資料表
// 依據COLSTAT=1來判斷為IDENTITY列不一定準確,沒有查過資料
create table table_tmp (table_name nvarchar(50))
insert into table_temp
select name from sysobjects where id in (
select id from syscolumns
where id in (select id from sysobjects
where type='u') and colstat=1 ) order by name
//定義一個遊標,獲得所有要導資料的表
declare cur_tab cursor for select table_name from table_tmp
declare @name nvarchar(40)
declare @sql nvarchar(2000)
begin
open cur_tab;
fetch cur_tab into @name;
while(@@fetch_status=0)
begin
// 將表的IDENTITY_INSERT屬性設定為ON,準備匯入資料
set @sql='set identity_insert '+ @name + ' on;';
print(@sql);
--exec(@sql);
// 這裡聲明帶參數的遊標,取得當前表的所有列,因為表具有IDENTITY的列時,
// 必須要將表的列全部寫出來啊,才可以匯入
exec('
declare cur_col cursor
for select name from syscolumns
where id= (
select id from sysobjects
where type=''u''
and name='''+ @name +''')');
declare @col nvarchar(20);
declare @in_sql nvarchar(2000);
declare @in_col nvarchar(1000);
set @in_col='';
open cur_col ;
fetch cur_col into @col;
while(@@fetch_status=0)
begin
set @in_col=@in_col+@col+',';
fetch cur_col into @col;
end;
set @in_col=substring(@in_col,1,len(@in_col)-1);
set @in_sql='insert into '+@name +' ('+@in_col+') select '+@in_col+ ' from DBVIP.src_db.dbo.'+@name;
print(@in_sql);
--exec(@in_sql);
close cur_col;
deallocate cur_col
set @sql='set identity_insert '+ @name + ' off;';
print(@sql);
--exec(@sql);
fetch cur_tab into @name;
end;
close cur_tab;
deallocate cur_tab
end;