SQL 批量插入
SQL Bulk Insert
我有一个发送给我的 csv 文件。我已将该文件放入 Notepad++,它将 ROWTERMINATOR 显示为 CRLF。这意味着我在 SQL 中使用 \r\n 作为我的 ROWTERMINATOR 对吗?
这是文件格式(每行末尾有 CRLF):
2020/02/10 03:00:00,2020/02/11 02:59:59,2
101,1,5,1,7,10950,0,10950,0,1429
101,1,5,2,7,28878,5500,28878,0,0
101,1,5,3,4,9525,1200,9525,0,0
101,1,5,4,1,7686,0,7686,0,0
101,1,5,7,3,9094,1300,9094,0,0
我基本上需要从第一个单元格中提取日期,然后忽略该行的其余部分,我已经这样做了:
SET @sql =
'BULK INSERT #date
FROM ' + '''' + @fileName + '''' + '
WITH
(
FIRSTROW = 1,
LASTROW = 1,
ROWTERMINATOR = ' + '''' + ',' + '''' + ',
FIELDTERMINATOR = ' + '''' + ',' + '''' + ',
CODEPAGE=' + '''' + '65001' + '''' + ',
KEEPNULLS
)'
然后拉取剩余的 5 行数据,这不起作用,因为它将所有数据包装到一行中:
SET @sql =
'BULK INSERT #fileColumns
FROM ' + '''' + @fileName + '''' + '
WITH
(
FIRSTROW = 2,
FIELDTERMINATOR = ' + '''' + ',' + '''' + ',
ROWTERMINATOR = ' + '''' + '\r\n' + '''' + ',
CODEPAGE=' + '''' + '65001' + '''' + ',
KEEPNULLS
)'
我也试过 \n 作为 ROWTERMINATOR,它给我最后 4 行,因为第一行数据被包装到第一行中。
我不太喜欢我必须这样做的方式,但它确实有效:
SET @sql =
'BULK INSERT #fileColumns
FROM ' + '''' + @fileName + '''' + '
WITH
(
FIRSTROW = 2,
ROWTERMINATOR = ' + '''' + '\n' + '''' + ',
CODEPAGE=' + '''' + '65001' + '''' + ',
KEEPNULLS
)'
EXEC (@sql)
WITH Split AS (
SELECT Column1,
Split.value,
ROW_NUMBER() OVER(PARTITION BY Column1 ORDER BY (SELECT NULL)) AS RowNumber
FROM #fileColumns
CROSS APPLY STRING_SPLIT(Column1, ',') AS Split
)
SELECT [1] AS ProfitCenterId,
[2] AS CheckTypeId,
[3] AS MealPeriodId,
[4] AS TenderId,
[5] AS NumberOfTenders,
[6] AS TenderAmount,
[7] AS TipAmount,
[8] AS ReceivedAmount,
[9] AS BreakageAmount,
[10] AS ChangeGiven
FROM Split
PIVOT
(
MAX(value)
FOR RowNumber IN ([1], [2], [3], [4], [5], [6], [7], [8], [9], [10])
) AS piv
绝对不漂亮,但它会做。
我有一个发送给我的 csv 文件。我已将该文件放入 Notepad++,它将 ROWTERMINATOR 显示为 CRLF。这意味着我在 SQL 中使用 \r\n 作为我的 ROWTERMINATOR 对吗?
这是文件格式(每行末尾有 CRLF):
2020/02/10 03:00:00,2020/02/11 02:59:59,2
101,1,5,1,7,10950,0,10950,0,1429
101,1,5,2,7,28878,5500,28878,0,0
101,1,5,3,4,9525,1200,9525,0,0
101,1,5,4,1,7686,0,7686,0,0
101,1,5,7,3,9094,1300,9094,0,0
我基本上需要从第一个单元格中提取日期,然后忽略该行的其余部分,我已经这样做了:
SET @sql =
'BULK INSERT #date
FROM ' + '''' + @fileName + '''' + '
WITH
(
FIRSTROW = 1,
LASTROW = 1,
ROWTERMINATOR = ' + '''' + ',' + '''' + ',
FIELDTERMINATOR = ' + '''' + ',' + '''' + ',
CODEPAGE=' + '''' + '65001' + '''' + ',
KEEPNULLS
)'
然后拉取剩余的 5 行数据,这不起作用,因为它将所有数据包装到一行中:
SET @sql =
'BULK INSERT #fileColumns
FROM ' + '''' + @fileName + '''' + '
WITH
(
FIRSTROW = 2,
FIELDTERMINATOR = ' + '''' + ',' + '''' + ',
ROWTERMINATOR = ' + '''' + '\r\n' + '''' + ',
CODEPAGE=' + '''' + '65001' + '''' + ',
KEEPNULLS
)'
我也试过 \n 作为 ROWTERMINATOR,它给我最后 4 行,因为第一行数据被包装到第一行中。
我不太喜欢我必须这样做的方式,但它确实有效:
SET @sql =
'BULK INSERT #fileColumns
FROM ' + '''' + @fileName + '''' + '
WITH
(
FIRSTROW = 2,
ROWTERMINATOR = ' + '''' + '\n' + '''' + ',
CODEPAGE=' + '''' + '65001' + '''' + ',
KEEPNULLS
)'
EXEC (@sql)
WITH Split AS (
SELECT Column1,
Split.value,
ROW_NUMBER() OVER(PARTITION BY Column1 ORDER BY (SELECT NULL)) AS RowNumber
FROM #fileColumns
CROSS APPLY STRING_SPLIT(Column1, ',') AS Split
)
SELECT [1] AS ProfitCenterId,
[2] AS CheckTypeId,
[3] AS MealPeriodId,
[4] AS TenderId,
[5] AS NumberOfTenders,
[6] AS TenderAmount,
[7] AS TipAmount,
[8] AS ReceivedAmount,
[9] AS BreakageAmount,
[10] AS ChangeGiven
FROM Split
PIVOT
(
MAX(value)
FOR RowNumber IN ([1], [2], [3], [4], [5], [6], [7], [8], [9], [10])
) AS piv
绝对不漂亮,但它会做。