我要求将表数据导出为平面文件(.csv格式),每个文件只包含5000条记录。如果表有10000条记录,那么它必须创建2个文件,每个文件有5000条记录。表中的记录将每天增加。所以基本上我正在寻找一种动态解决方案,它将“n”个记录导出到“n”个文件,每个文件只有5000条记录。
*一个简单的可视化: 假设该表有10230条记录。我需要的是:
File_1.csv - 1到5000条记录
File_2.csv - 5001到10000条记录
File_3.csv - 10001到10230记录*
我已经尝试过上述逻辑的BCP命令。可以使用数据流任务完成吗?
答案 0 :(得分:1)
不,这不是SSIS本能支持的东西。
脚本任务或作为目的地的脚本组件可以实现此目的,但是您需要重新发明轮子的重要部分,并且需要所有文件处理。
第一步是以可重复的方式向来自源的所有行添加行号。这可能就像SELECT *, ROW_NUMBER() OVER (ORDER BY MyTablesKey) AS RN FROM dbo.MyTable
现在您有一个与每行关联的单调递增值,如果您采用ForEach方法,则可以使用referenced答案来提取给定范围内的数据。
如果您可以对您拥有的数据桶/文件数量做出合理的上限,那么您可以使用一些分析函数来指定分组的大小。然后将所有数据输入到数据流中,并且您有一个条件拆分,其上限值为输出缓冲区,前往平面文件目标。
另一种方法是按原样导出文件,然后使用类似PowerShell的内容将其拆分为更小的单元。 Unix很不错,因为它们只有split作为本机方法。
答案 1 :(得分:0)
嗯,可以使用标准的SSIS组件和SQL 2012+来完成。想法如下 - 使用SELECT ... ORDER BY ... OFFSET <Row offset> ROWS FETCH NEXT <Row number> ROWS
作为桶源,并将其与FOR容器和带有表达式的Flat File Destination一起使用
更多细节:
"SELECT count(*) FROM ... ORDER BY ... OFFSET "+(DT_WSTR,20)[User::Iterator]*[User::Bucket_Size]+" ROWS "
创建SQL_rowcount变量。此命令为您提供当前存储桶中的剩余行数。 "SELECT .. FROM ... ORDER BY ... OFFSET "+(DT_WSTR,20)[User::Iterator]*[User::Bucket_Size]+" ROWS FETCH NEXT "+(DT_WSTR,20)[User::Bucket_Size]+" ROWS"
创建一个字符串变量SQL_bucket。就是这样 如果在导出期间未修改源表,则可以对其进行优化;首先(在For循环之前)获取行数并计算出桶的数量,并执行此迭代次数。因此,您可以避免在循环中重复选择count(*)语句。