很遗憾,BCP 的 batch_size 参数不控制输出。
我进行这种拆分的方式:
1 - 简单但不可重复:创建一个命令文件 (.cmd),在表上针对特定行范围运行多个 BCPs。这可能需要在表上使用基于 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 创建所需数量的新文件每个字节中的字节数(注意:按行分割是一个更好的主意 IMO)。使用“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;
--Use WHILE to loop as needed--
DECLARE @sql AS VARCHAR(MAX);
--Add code to generate dynamic SQL here--
DECLARE @bcp AS VARCHAR(MAX);
SELECT @bcp='BCP "'+@sql+'" queryout C:\MyFolder\MyFile_'+@loop+'.csv';
最后说明:如果您在数据中使用任何 NVARCHAR 字段,则需要使用 -w 标志并注意输出将采用 UTF-16LE 格式。我会强烈建议使用iconv(再次来自'Cygwin')将其转换为UTF-8,然后再尝试在Hadoop中对其进行任何操作。