如何在 SSMS 上导入带有 TIME 列的 CSV (SQL)

How to import a CSV with a TIME column on SSMS (SQL)

我有一个格式如下的 CSV

  COL1     |   COL2
 20211002  |  163136
(YYYYMMDD) | (HHMMSS)

在 SQL 我正在创建具有以下格式的 table

CREATE TABLE dbo.[table] (
    [COL1] DATE,
    [COL2] TIME,
);

批量加载:

BULK INSERT dbo.[table]
FROM 'path\df_2.csv'
WITH (FIRSTROW=2, MAXERRORS=0, FIELDTERMINATOR=',' , ROWTERMINATOR='\n');

COL1 工作正常并且正在读取,但是 COL02 给我带来了麻烦并给出了以下错误

Msg 4864, Level 16, State 1, Line 17
Bulk load data conversion error (type mismatch or invalid character for the specified codepage) for row 2, column 13 (COL2).

我该如何解决这个问题?

问题是您的 COL2 数据不符合 hh:mm:ss 的 t-sql TIME 格式。如果您无法重做您的源文件以将该列转换为正确的格式,您可以在加载期间使用 OPENROWSET 转换数据,而不是使用 BULK LOAD.

首先创建一个这样的格式文件(将其命名为 fmt.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=","/>
  <FIELD ID="2" xsi:type="CharTerm" TERMINATOR="\n"/>
 </RECORD>
 <ROW>
  <COLUMN SOURCE="1" NAME="COL1" xsi:type="SQLDATE"/>
  <COLUMN SOURCE="2" NAME="COL2" xsi:type="SQLVARYCHAR"/>
 </ROW>
</BCPFORMAT>

然后使用它来批量加载您的数据:

INSERT dbo.[table] (COL1, COL2)
SELECT
    COL1,
    CONCAT(LEFT(COL2,2), ':', SUBSTRING(COL2, 3, 2),':', SUBSTRING(COL2, 5, 2)) COL2
FROM OPENROWSET
(
    BULK 'path\df_2.csv',
    CODEPAGE = 'RAW',
    FIRSTROW = 2,
    FORMATFILE = 'path\fmt.xml' --the path to your format file from above
) AS csv;

这里的技巧是 OPENROWSET 在批量加载期间将 COL2 的数据作为 VARCHAR 读取到内存中,如格式文件中指定的那样。然后你可以使用普通的 t-sql 来操作它,当你将内存中的数据插入你的 table.

时,将它转换成 TIME 的兼容格式

假设您的 COL2 数据在所有情况下都是 6 个字符,应该为您完成。如果您的数据在某些地方不是 6 个字符,您需要在 SELECT;

中考虑到这一点