SQL Server导入CSV数据:旧账号映射新IDENTITY账号的实现方案
完全可以不用SSIS!用BULK IMPORT或者OPENQUERY都能实现旧账号到新自增ID的映射导入,下面给你拆解两种实用方案:
方案一:BULK IMPORT + 临时表关联替换
这是最常用的方式,步骤清晰且性能不错:
- 创建临时表存储原始交易数据
先建一个临时表,用来承接CSV里的旧账号和转账金额:
CREATE TABLE #TempTransactions ( OldFromAccount INT, OldToAccount INT, TransferAmount DECIMAL(18,2) );
- 用BULK IMPORT导入CSV数据
根据你的CSV格式调整参数(比如分隔符、是否有表头):
BULK IMPORT #TempTransactions FROM 'C:\YourFileDirectory\Transactions.csv' WITH ( FIELDTERMINATOR = ',', -- CSV字段分隔符,一般是逗号 ROWTERMINATOR = '\n', -- 行结束符,Windows系统也可能是'\r\n' FIRSTROW = 2, -- 如果CSV第一行是表头,就跳过第一行 TABLOCK -- 加表锁提升导入速度,数据量大时推荐 );
- 关联Account表替换账号,插入正式表
关键前提:你导入Accounts.csv到Account表时,一定要保留旧AccountID作为单独列(比如命名为OldAccountID),不然没有映射关系没法替换!
假设你的正式交易表是dbo.Transactions,执行以下插入语句:
INSERT INTO dbo.Transactions (FromAccountID, ToAccountID, TransferAmount) SELECT acc_from.AccountID AS FromAccountID, acc_to.AccountID AS ToAccountID, temp.TransferAmount FROM #TempTransactions temp -- 关联旧转出账号到新ID JOIN dbo.Account acc_from ON temp.OldFromAccount = acc_from.OldAccountID -- 关联旧转入账号到新ID JOIN dbo.Account acc_to ON temp.OldToAccount = acc_to.OldAccountID;
- 清理临时表(可选)
DROP TABLE #TempTransactions;
方案二:OPENQUERY + 链接服务器直接关联
如果不想用临时表,也可以把CSV当成一个数据源,通过链接服务器直接关联查询:
- 配置CSV链接服务器
需要先在SQL Server上安装Microsoft ACE OLE DB Provider(注意对应32/64位版本),然后创建链接服务器:
EXEC sp_addlinkedserver @server = 'CSV_Linked', @srvproduct = 'ACE OLEDB', @provider = 'Microsoft.ACE.OLEDB.12.0', @datasrc = 'C:\YourFileDirectory\', -- CSV所在的文件夹路径,不是单个文件 @provstr = 'Text;HDR=Yes;FMT=Delimited'; -- HDR=Yes表示CSV有表头
- 用OPENQUERY查询并插入数据
直接通过链接服务器读取CSV,同时关联Account表替换账号:
INSERT INTO dbo.Transactions (FromAccountID, ToAccountID, TransferAmount) SELECT acc_from.AccountID, acc_to.AccountID, tx.TransferAmount FROM OPENQUERY(CSV_Linked, 'SELECT FromAccount, ToAccount, TransferAmount FROM Transactions.csv') tx JOIN dbo.Account acc_from ON tx.FromAccount = acc_from.OldAccountID JOIN dbo.Account acc_to ON tx.ToAccount = acc_to.OldAccountID;
重要注意事项
- 数据校验:导入前建议先检查有没有无法匹配的旧账号,避免插入失败:
-- 用临时表的情况 SELECT * FROM #TempTransactions temp LEFT JOIN dbo.Account acc_from ON temp.OldFromAccount = acc_from.OldAccountID LEFT JOIN dbo.Account acc_to ON temp.OldToAccount = acc_to.OldAccountID WHERE acc_from.AccountID IS NULL OR acc_to.AccountID IS NULL;
- 权限问题:SQL Server服务账号需要有CSV所在文件夹的读取权限,
BULK IMPORT还需要ADMINISTER BULK OPERATIONS权限。 - 性能对比:数据量较大时,
BULK IMPORT的速度会远快于OPENQUERY,因为前者是批量导入机制。
内容的提问来源于stack exchange,提问作者dualcoredba
相关产品推荐
相关产品推荐

