【问题标题】:SQL Server 2017 - Bulk Insert SQLBIT type using format file and FORMAT = CSV parameterSQL Server 2017 - 使用格式文件和 FORMAT = CSV 参数批量插入 SQLBIT 类型
【发布时间】:2020-08-17 16:47:22
【问题描述】:

我有一个输入 CSV 文件。 CSV 中的数据包含在文本限定符(双引号)中,因此对于批量插入以在插入表时删除双引号,我使用 FORMAT = 'CSV' 参数。

CSV 中的一列包含布尔数据 (TRUE/FALSE),我希望将其作为 1 和 0 插入 SQL 表 (SQL 2017) 中,其数据类型为位。因此,在格式文件中,我将其类型指定为 SQLBIT,其他类型指定为 SQLCHAR。

但是批量插入失败并出现错误:

Cannot bulk load CSV file. Invalid field parameters are specified for source column number 3 in the format file. All data fields must be either character or Unicode character with terminator when CSV format is specified.

从上面的错误中我了解到的一件事是,当我使用 FORMAT = 'CSV' 参数时,我不能在格式文件中使用 SQLBIT。使用 SQLCHAR 它可以工作,但是在 SQL 表中我必须将数据类型更改为 varchar(5) 而不是我不想要的位。

那么有没有一种方法可以在格式文件中同时使用 SQLBIT,同时使用 FORMAT = 'CSV' 参数,或者如果不是 SQLBIT,那么任何其他工作方法都可以在不更改数据类型的情况下将 SQL 表中的值插入为 1 和 0?

输入 CSV:

Id,Address,IsActive,CreatedDate
"I1","NY,U.S.","TRUE","2020-01-01"
"I2","Perth,Aus","FALSE","2020-02-01"

SQL 表:

Create table dbo.Bulk_Fmt_Test
(
   Id char(2) not null,
   Address varchar(255),
   IsActive bit,
  CreatedDate datetime2
)

格式化文件:

14.0
4
1 SQLCHAR 0 9999 "," 1 Id ""
2 SQLCHAR 0 9999 "," 2 Address ""
3 SQLBIT  0  1   "," 3 IsActive ""
4 SQLCHAR 0 9999 "\n" 4 CreatedDate ""

批量插入查询:

BULK INSERT dbo.Bulk_Fmt_Test from 'C:\Data\Sample1.csv'
WITH (FORMAT = 'CSV', FIRSTROW = 2, FormatFile = 'C:\Data\Sample.fmt');

【问题讨论】:

  • 您可能不得不使用临时表。

标签: sql-server bulkinsert


【解决方案1】:

格式文件描述的是文件格式而不是表格。字符串“TRUE”和“FALSE”是字符数据,而不是SQLBIT 格式规范指示的二进制位值。这些布尔字符串值可以在 T-SQL 中隐式转换为位,但 BULK INSERT(和 BCP)不这样做。

作为一种解决方法,在格式文件中指定SQLCHAR 并使用INSERT … FROM OPENROWSET … BULK 隐式转换布尔值。我使用 Windows CR/LF 行终止符测试了下面的示例,而不是像您的问题那样仅使用 LF,但我希望您也可以使用 LF 获得所需的结果:

14.0
4
1 SQLCHAR 0 9999 "," 1 Id ""
2 SQLCHAR 0 9999 "," 2 Address ""
3 SQLCHAR 0 5    "," 3 IsActive ""
4 SQLCHAR 0 9999 "\r\n" 4 CreatedDate ""

T-SQL 语句:

INSERT INTO dbo.Bulk_Fmt_Test(Id, Address, IsActive, CreatedDate)
SELECT Id, Address, IsActive, CreatedDate
FROM OPENROWSET(BULK N'C:\Data\Sample1.csv',
    FORMATFILE = N'C:\Data\Sample.fmt',
    FIRSTROW=2,
    FORMAT='CSV') AS source;

【讨论】:

    【解决方案2】:

    您可以先插入临时表,然后对其进行验证并插入到您的表中。因此,您可以插入而不会出错。

    CREATE TABLE #Bulk_Fmt_Test(
       Id varchar(100),
       Address varchar(300),
       IsActive varchar(10),
       CreatedDate varchar(20)
    )
    
    BULK INSERT #Bulk_Fmt_Test from 'C:\Data\Sample1.csv'
    WITH (FORMAT = 'CSV', FIRSTROW = 2, FormatFile ='C:\Data\Sample.fmt');
    
    INSERT INTO Bulk_Fmt_Test (Id, Address, IsActive, CreatedDate)
    SELECT
    TRY_CONVERT(char(2), Id),
    LEFT(Address, 255),
    ISNULL(TRY_CONVERT(bit, IsActive), IIF(IsActive = 'TRUE', 1, 0)),
    TRY_CONVERT(datetime2, CreatedDate)
    FROM #Bulk_Fmt_Test
    

    注意:TRY_CONVERT 是兼容级别 110 及更高级别中的保留关键字。 详细资料here

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-06-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多