使用sql bulkload或openrowset导入.csv文件以缺少列数据

时间:2018-09-10 06:05:12

标签: sql sql-server bcp openrowset

。我有一个 csv 文件。数据如下所示,

___________________________________________________________
StateName       |  City                 |  Score1 |  Score2 |
________________|_______________________|_________|_________|
                |                       |         |         |
New South Wales |  Albury (C)           |  979    |   967   |  
                |  Armidale Dumaresq (A)|  987    |   985   |  
                |  Ashfield (A)         |  1015   |   1031  |
________________|_______________________|_________|_________| 
Victoria        |  Alpine (S)           |   987   |   970   |
                |  Ararat (RC)          |   951   |   938   |
________________|_______________________|_________|_________| 

现在,我想通过 SQL BCP or OPENROWSET 中上传。但是要抓住的是缺少状态名称的记录,我想复制初始声明的状态名称。

例如,在上面的 row# 2 中。我希望 StateName 的城市为 "New South Wales" 。如何使用 "Armidale Dumaresq (A)" 做到这一点?我真的不想只为这个小东西创建一个新的应用程序。任何解决方案将不胜感激。

1 个答案:

答案 0 :(得分:1)

假设您的csv文件另存为E:\Temp\Test.csv

StateName,City,Score1,Score2
New South Wales,Albury (C),979,967
,Armidale Dumaresq (A),987,985
,Ashfield (A),1015,1031
Victoria,Alpine (S),987,970
,Ararat (RC),951,938

您可以按如下方式在E:\Temp\Test.xml中写BCP format file

<?xml version="1.0"?> 
<BCPFORMAT xmlns="http://schemas.microsoft.com/sqlserver/2004/bulkload/format" 
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> 
 <RECORD> 
  <FIELD ID="1" xsi:type="CharTerm" TERMINATOR="," MAX_LENGTH="200"/> 
  <FIELD ID="2" xsi:type="CharTerm" TERMINATOR="," MAX_LENGTH="200"/> 
  <FIELD ID="3" xsi:type="CharTerm" TERMINATOR="," MAX_LENGTH="8"/> 
  <FIELD ID="4" xsi:type="CharTerm" TERMINATOR="\r\n" MAX_LENGTH="8"/> 
 </RECORD> 
 <ROW> 
  <COLUMN SOURCE="1" NAME="StateName" xsi:type="SQLNVARCHAR"/> 
  <COLUMN SOURCE="2" NAME="City" xsi:type="SQLNVARCHAR"/> 
  <COLUMN SOURCE="3" NAME="Score1" xsi:type="SQLINT"/> 
  <COLUMN SOURCE="4" NAME="Score2" xsi:type="SQLINT"/> 
 </ROW> 
</BCPFORMAT>

并使用查询:

WITH Src AS
(
    SELECT ROW_NUMBER() OVER (ORDER BY (SELECT 1)) N, * 
    FROM OPENROWSET(BULK N'E:\Temp\Test.csv', FORMATFILE = 'E:\Temp\Test.xml', FIRSTROW = 2) As Blk
), NameGroup AS
(
    SELECT *, COUNT(StateName) OVER(ORDER BY N ROWS UNBOUNDED PRECEDING) GroupName FROM Src
)
SELECT FIRST_VALUE(StateName) OVER (PARTITION BY GroupName ORDER BY N ROWS UNBOUNDED PRECEDING) StateName, City, Score1, Score2
FROM NameGroup

结果

StateName         City                    Score1   Score2
----------------- ----------------------- -------- ------
New South Wales   Albury (C)              979      967
New South Wales   Armidale Dumaresq (A)   987      985
New South Wales   Ashfield (A)            1015     1031
Victoria          Alpine (S)              987      970
Victoria          Ararat (RC)             951      938