Импорт файла .csv с использованием sql bulkload или openrowset для отсутствующих данных столбца - PullRequest
0 голосов
/ 10 сентября 2018

.У меня есть файл 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)". Как я могу сделать это, используя sql bulk load? Я действительно не хочу создавать новое приложение только для этой маленькой вещи. Любое решение будет оценено.

1 Ответ

0 голосов
/ 10 сентября 2018

Предполагается, что ваш 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

Вы можете записать файл формата BCP в E:\Temp\Test.xml следующим образом:

<?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
...