如何将CSV整列替换为对应外键 批量导入SQL Server数据表
结论
这不是数据库设计缺陷,你当前的表结构完全符合第三范式要求:将股票静态基础信息和动态行情数据拆表、通过外键关联,是避免symbol字段冗余、防止代码录入错误的标准设计,不需要调整现有表结构。
你考虑的「临时表中转+关联写入」就是千行级数据场景下成本最低、实现最简单的方案,全程在SSMS里操作即可,不需要额外开发工具或脚本,具体实现步骤如下:
操作步骤
1. 建CSV中转临时表
临时表字段和CSV表头完全一一对应,不设置外键、不做字段映射,仅做数据中转使用:
CREATE TABLE #StockCsvTemp ( symbol VARCHAR(20) NOT NULL, date VARCHAR(8) NOT NULL, -- 兼容CSV里20220627格式的数字日期,导入后再做类型转换 open DECIMAL(10,3) NOT NULL, high DECIMAL(10,3) NOT NULL, low DECIMAL(10,3) NOT NULL, close DECIMAL(10,3) NOT NULL, vol BIGINT NOT NULL );
字段精度、长度可以根据你的实际业务数据调整,避免导入时出现类型截断错误。
2. 将CSV全量导入临时表
两种方式任选,千行数据导入耗时均在1秒内:
- 无代码方式:右键目标数据库 → 任务 → 导入数据,数据源选择「平面文件源」选中本地CSV文件,目标选择当前连接的SQL Server实例,指定导入表为刚创建的
#StockCsvTemp,按向导默认配置走完即可,记得勾选「跳过首行表头」。 - 命令方式:直接执行
BULK INSERT命令完成导入:
BULK INSERT #StockCsvTemp FROM 'C:\你的文件本地路径\stock_data.csv' -- 替换为实际CSV绝对路径 WITH ( FORMAT = 'CSV', FIRSTROW = 2, -- 跳过CSV表头行 FIELDTERMINATOR = ',', ROWTERMINATOR = '\n', TABLOCK );
3. 关联映射写入正式行情表
通过JOIN已有的Stock基础表,将CSV中的symbol替换为对应股票主键id,一条SQL即可完成全量写入:
INSERT INTO [Stock Data] (stock_id, date, open, high, low, close, vol) SELECT s.id AS stock_id, CONVERT(DATE, stg.date, 112) AS date, -- 112对应YYYYMMDD日期格式,和你示例里的20220627格式完全匹配 stg.open, stg.high, stg.low, stg.close, stg.vol FROM #StockCsvTemp stg INNER JOIN Stock s ON stg.symbol = s.symbol;
注意事项
- 如果执行插入后返回的影响行数和CSV总行数不一致,执行下面的语句可以快速找出CSV中存在、但
Stock基础表未维护的股票代码,补全基础表数据后重跑插入即可:
SELECT stg.symbol, COUNT(*) AS data_count FROM #StockCsvTemp stg LEFT JOIN Stock s ON stg.symbol = s.symbol WHERE s.id IS NULL GROUP BY stg.symbol;
- 这套方案在十万行级别的CSV导入场景下依然有稳定的性能表现,不需要引入额外ETL工具。如果需要定期导入行情数据,可以把上述逻辑封装为存储过程,后续每次导入仅需替换文件路径执行即可。
- 不要为了简化导入流程直接在
Stock Data表中冗余存储symbol字段、移除外键关联,后续做数据清洗、股票信息维护时会出现大量数据不一致的问题。
内容的提问来源于stack exchange,提问作者Spinky
相关产品推荐
相关产品推荐

