遗憾的是,BCP的batch_size参数不能控制输出。
我处理这种拆分的方式有:
1 - 简单但不可重复:创建一个命令文件(.cmd),对特定的行范围运行多个BCP
。这可能需要在表上使用基于IDENTITY(1,1)
的主键。
bcp "SELECT * FROM MyTable WHERE Id BETWEEN 0 AND 10000000" queryout …
bcp "SELECT * FROM MyTable WHERE Id BETWEEN 10000000 AND 20000000" queryout …
2 - 简单易行且可以重复使用,需要大量磁盘空间: BCP
将整个表导出到一个文件中,然后使用 split
创建所需数量的新文件,每个文件的大小都相同(注意:按行拆分可能是更好的选择)。使用'Cygwin'(GnuWin32不再维护)安装split
和其他任何你需要的工具。
bcp MyDb.MySchema.MyTable out C:\MyFile.csv -T -w
split -b 10737418240 C:\MyFile.csv C:\MySplitFile_
生成以下文件。
C:\MySplitFile_aaa
C:\MySplitFile_aab
…
3 - 复杂但可重复,需要可能不安全的 T-SQL: 使用 xp_cmdshell
函数在存储过程中调用 BCP 并通过迭代表来实现。
DECLARE @loop AS INT;
DECLARE @sql AS VARCHAR(MAX);
DECLARE @bcp AS VARCHAR(MAX);
SELECT @bcp='BCP "'+@sql+'" queryout C:\MyFolder\MyFile_'+@loop+'.csv';
最终说明:如果你的数据中使用了任何NVARCHAR字段,则需要使用-w
标志,并且要注意输出将是UTF-16LE格式。我强烈建议在尝试在Hadoop中处理数据之前,使用iconv
(再次来自'Cygwin')将其转换为UTF-8格式。