我使用SqlBulkCopy將數據以編程方式從Excel導出到SQL Server 2005。它工作得很好,我唯一的問題是,它不保留我在Excel文件中的行序列。我沒有要排序的列,我只想按照它們出現在Excel電子表格中的順序插入記錄。如何使用SqlBulkCopy保持行順序?
我無法修改Excel文件,而必須使用我所得到的。按任何現有列進行排序會破壞序列。
請幫助。
P.S.結束將ID列插入到電子表格中,看起來像在導出/導入過程中無法保持訂單
我使用SqlBulkCopy將數據以編程方式從Excel導出到SQL Server 2005。它工作得很好,我唯一的問題是,它不保留我在Excel文件中的行序列。我沒有要排序的列,我只想按照它們出現在Excel電子表格中的順序插入記錄。如何使用SqlBulkCopy保持行順序?
我無法修改Excel文件,而必須使用我所得到的。按任何現有列進行排序會破壞序列。
請幫助。
P.S.結束將ID列插入到電子表格中,看起來像在導出/導入過程中無法保持訂單
我不認爲行排序是由SQL指定或保證,除非您使用「ORDER BY」子句。
由比爾·沃恩後(http://betav.com/blog/billva/2008/08/sql_server_indexing_tips_and_t.html):
使用排序:即使一個表有 一個聚集索引(存儲在物理順序 數據)時,SQL Server 並不保證除非使用了ORDER BY子句 ,否則將以該(或任何特定) 順序返回的行將爲 。
與信息的另一個鏈接:
http://sqlblogcasts.com/blogs/simons/archive/2007/08/21/What-is-the-position-of-a-row--.aspx
如果您可以將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」對您的數據庫和您的訂單將是相同的電子表格。
您還可能能夠在您的表中的數據加載過程中定義身份列自動遞增。這樣,您可以稍後再次對相同順序的記錄進行排序。
訂單被插入時混入了。你的方法將無法工作 – 2008-10-10 19:17:42
經過大量研究,似乎很明顯,由於Microsoft提供了大量插入命令,所以無法保留行插入命令。您必須自己直接將ID列添加到導入文件中,使用shell或其他外部腳本,否則您不需要。它似乎是微軟需要添加的一個必需(而且很容易)的功能,但是經過十多年沒有任何進展,這種情況不會發生。
但是我需要在導入文件中保存實際的記錄順序,因爲如果設置的列具有相同的值,較高的記錄將取代較低的記錄。
所以我走了一條不同的路線。我的制約因素:
我喜歡使用Powershell爲每行創建有序插入語句,然後在Sql中運行的邏輯。它基本上是將每個記錄排隊等待每個插入,而不是BULK插入。是的,它會工作,但它也會很慢。我經常擁有500K +行的文件。我需要快速的東西。
所以我整個XML跑。批量將文件直接上傳到單個XML變量中。這將保留記錄的順序,因爲每個記錄都添加到XML中。然後解析XML變量並將結果插入表中,同時添加標識列。
有一個假設,即導入文件是一個標準的文本文件,每個記錄在一個換行結束(CHAR(13)+ CHAR(10))
我的方法有兩個步驟:
執行IMPORT SQL語句(使用OPENROWSET),使用XML標記封裝每個記錄。將結果捕獲到一個XML變量中。
通過解析XML標記變量到一個表中,加入遞增[ID]列。
---------------------------------
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);
---------------------------------
XML標記替換每個換行。
如果文件以換行結束,這將導致在結尾添加一個空白行。只需刪除最後一行。
我使用動態SQL,所以我可以通過在文件名和將ID設置爲開始在1或0(如果有一個標題行)寫到我的過程這一點。
我能夠對抗的300K記錄的文件中約5秒鐘運行此。
由於SQL表本質上是無序的,以什麼方式,你可以告訴大家,插入順序是不同的 - 自動增量列? – 2008-10-10 00:34:45