Sql server 如何使用SqlBulkCopy保持行顺序?
我正在使用SqlBulkCopy以编程方式将数据从Excel导出到SQLServer2005。它工作得很好,我唯一的问题是它没有保留Excel文件中的行序列。我没有要排序的列,我只希望这些记录以它们在Excel电子表格中显示的相同顺序插入 我不能修改Excel文件,必须使用我所拥有的。按任何现有列进行排序都会中断序列 请帮忙Sql server 如何使用SqlBulkCopy保持行顺序?,sql-server,excel,import,export,sqlbulkcopy,Sql Server,Excel,Import,Export,Sqlbulkcopy,我正在使用SqlBulkCopy以编程方式将数据从Excel导出到SQLServer2005。它工作得很好,我唯一的问题是它没有保留Excel文件中的行序列。我没有要排序的列,我只希望这些记录以它们在Excel电子表格中显示的相同顺序插入 我不能修改Excel文件,必须使用我所拥有的。按任何现有列进行排序都会中断序列 请帮忙 最后,在电子表格中插入ID列,看起来在导出/导入过程中无法保持顺序如果您可以将excel电子表格保存为CSV,则很容易使用任何脚本语言生成INSERT语句列表,这些语句将以
最后,在电子表格中插入ID列,看起来在导出/导入过程中无法保持顺序如果您可以将excel电子表格保存为CSV,则很容易使用任何脚本语言生成INSERT语句列表,这些语句将以与电子表格完全相同的顺序执行。下面是Groovy中的一个快速示例,但任何脚本语言都可以轻松地完成此任务:
def file1 = new File('c:\\temp\\yourSpreadsheet.csv')
def file2 = new File('c:\\temp\\yourInsertScript.sql')
def reader = new FileReader(file1)
def writer = new FileWriter(file2)
reader.transformLine(writer) { line ->
fields = line.split(',')
text = """INSERT INTO table1 (col1, col2, col3) VALUES ('${fields[0]}', '${fields[1]}', '${fields[2]}');"""
}
然后,您可以对数据库执行“yourInsertScript.sql”,您的顺序将与电子表格相同。我认为sql不会指定或保证行顺序,除非您使用“order by”子句 来自比尔·沃恩()的帖子: 使用Order By:即使表已 聚集索引(用于存储 数据(按物理顺序排列),SQL Server 不保证行将被删除 以该方式返回(或任何特定) 订购,除非订购依据条款生效 用过 另一个信息链接:
您还可以在表中定义一个标识列,该列在数据加载期间自动递增。通过这种方式,您可以在以后希望记录再次按相同顺序排序时对其进行排序。经过大量研究后,似乎很明显,使用批量插入命令无法保留行顺序,因为它是由Microsoft编写的。您要么自己直接将ID列添加到导入文件中,要么使用shell或其他外部脚本,要么不使用。这似乎是微软需要(而且很容易)添加的功能,但在他们十多年一无所获之后,这不会发生 然而,我需要在导入后保留导入文件中的实际记录顺序,因为如果集合列具有相同的值,则较高的记录将取代较低的记录 所以我走了另一条路。我的限制是:
- 我根本无法更改源文件。(并开创了一个糟糕的先例!)
- 我无法使用外部脚本。太复杂了。它必须是一个简单的基于T-Sql的解决方案,没有CMD执行。这需要进入一个单一的过程,这样才能实现自动化
---------------------------------
Declare @X xml;
---------------------------------
SELECT @X=Cast('<X>'+Replace([BulkColumn],Char(13)+Char(10),'</X><X>')+'</X>' as XML)
FROM OPENROWSET (BULK N'\\FileServer\ImportFolder\ImportFile_20170120.csv',SINGLE_CLOB) T
---------------------------------
SELECT [Record].[X].query('.').value('.','varchar(max)') [Record]
,ROW_NUMBER() OVER (ORDER BY (SELECT 100)) [ID]
--Into #TEMP
FROM @X.nodes('X') [Record](X);
---------------------------------
---------------------------------
声明@xxml;
---------------------------------
选择@X=Cast(“”+Replace([BulkColumn],Char(13)+Char(10),“”)+XML格式)
从OPENROWSET(批量N'\\FileServer\ImportFolder\ImportFile\u 20170120.csv',单个\u CLOB)T
---------------------------------
选择[Record].[X]。查询('.')。值('.','varchar(max)')[Record]
,第_行编号()超过(订购人(选择100))[ID]
--进入#临时
来自@X.nodes('X')[记录](X);
---------------------------------
- XML标记替换每个换行符
- 如果文件以换行结束,这将导致在末尾添加一个空行。只需删除最后一行
我能够在大约5秒钟内对一个包含300K条记录的文件运行此操作。鉴于SQL表本身就是无序的,您如何判断插入顺序是不同的?一个自动递增列?插入过程中顺序会混淆。你的方法行不通