Sql server 在SQL Server中大容量插入部分引用的CSV文件

Sql server 在SQL Server中大容量插入部分引用的CSV文件,sql-server,csv,bulkinsert,Sql Server,Csv,Bulkinsert,我正在尝试导入一个正确引用的CSV文件,这意味着数据只有在包含逗号时才被引用,例如: 41, Terminator, Black 42, "Monsters, Inc.", Blue 我注意到,第一行导入正确,但第二行错误的方式表明引用的逗号被视为字段分隔符 我见过这样的建议 更改字段终止符的步骤 字段终止符='”,“' 然而,我的CSV文件只引用需要它的字段,所以我不相信这个建议会起作用 SQL Server的批量导入语句能否导入正确引用的CSV文件?如何?根据CSV格式规范,我认为数据引

我正在尝试导入一个正确引用的CSV文件,这意味着数据只有在包含逗号时才被引用,例如:

41, Terminator, Black
42, "Monsters, Inc.", Blue
我注意到,第一行导入正确,但第二行错误的方式表明引用的逗号被视为字段分隔符

我见过这样的建议

更改字段终止符的步骤

字段终止符='”,“'

然而,我的CSV文件只引用需要它的字段,所以我不相信这个建议会起作用


SQL Server的批量导入语句能否导入正确引用的CSV文件?如何?

根据CSV格式规范,我认为数据引用是否正确并不重要,只要它符合规范。如果语法分析器实现正确,则应该处理过多的引号<代码>字段终止符应为逗号,
行终止符
为行结束符-这表示标准CSV文件。是否尝试使用这些设置导入数据?

不幸的是,SQL Server将带引号的逗号解释为分隔符。这适用于BCP和批量插入

如果终止符字符出现在数据中,则解释为 一个终止符,不作为数据,该字符后面的数据是 解释为属于下一个字段或记录。所以,, 仔细选择你的终结者,确保他们永远不会出现 在您的数据中


您还可以考虑将OpenRowSet与CSV文本文件数据提供程序一起使用

对于任何版本的SQL Server>=2005,这都应该是可能的,尽管您需要启用该功能


我也遇到了同样的问题,数据偶尔会双引号引用一些文本。 我的解决方案是让批量加载导入双引号,然后对导入的数据运行替换

例如:

大容量插入码点\u tbl 来自“F:\Data\Map\CodePointOpen\Data\CSV\ab.CSV” 使用(FIRSTROW=1,FIELDTERMINATOR=',,rowdterminator='\n')

更新代码点\u tbl 设置邮政编码=替换(邮政编码“,”) 其中charindex(“”,邮政编码)>0

为了减少编写替换脚本的痛苦,只需从以下内容的结果中复制并粘贴所需内容:

select C.ColID, C.[name] as Columnname into #Columns
from syscolumns C
join sysobjects T on C.id = T.id
where T.[name] = 'User_tbl'
order by 1;

declare @QUOTE char(1);
set @QUOTE = Char(39);
select 'Update User_tbl set '+ColumnName+'=replace('+ColumnName+','
 + @QUOTE + '"' + @QUOTE + ',' + @QUOTE + @QUOTE + ');
GO'
from #Columns
where ColID > 2
order by ColID;
9.0
4
1       SQLCHAR       0       0     "\""      0     FIRST_QUOTE      SQL_Latin1_General_CP1_CI_AS
2       SQLCHAR       0       5     "\",\""   1     FNAME               SQL_Latin1_General_CP1_CI_AS
3       SQLCHAR       0       5     "\",\""   2     LNAME            SQL_Latin1_General_CP1_CI_AS
4       SQLCHAR       0       50    "\"\r\n"  3     COMPANY          SQL_Latin1_General_CP1_CI_AS
"col1"|"col2"
"val1"|"val2"
"val3"|"val4"

还有另一种解决办法

通过编辑fmt文件,将引号视为字段分隔符的一部分

有关详细信息,您可以查看以下内容:

上面链接的摘录:

删除引号的唯一方法是修改导入操作期间指定的列分隔符。这里唯一的缺点是,如果您检查要插入的数据,您将很快意识到每列的列分隔符是不同的(上面突出显示的分隔符)

因此,要为每列指定不同的列分隔符,如果计划使用大容量插入或BCP,则需要使用格式文件。如果为上述表格结构生成格式文件,则如下所示:

9.0
3
1       SQLCHAR       0       5       "\t"     1     FName              SQL_Latin1_General_CP1_CI_AS
2       SQLCHAR       0       5       "\t"     2     LName              SQL_Latin1_General_CP1_CI_AS
3       SQLCHAR       0       50      "\r\n"   3     Company            SQL_Latin1_General_CP1_CI_AS
修改格式文件以表示每列的正确列分隔符。要使用的新格式文件如下所示:

select C.ColID, C.[name] as Columnname into #Columns
from syscolumns C
join sysobjects T on C.id = T.id
where T.[name] = 'User_tbl'
order by 1;

declare @QUOTE char(1);
set @QUOTE = Char(39);
select 'Update User_tbl set '+ColumnName+'=replace('+ColumnName+','
 + @QUOTE + '"' + @QUOTE + ',' + @QUOTE + @QUOTE + ');
GO'
from #Columns
where ColID > 2
order by ColID;
9.0
4
1       SQLCHAR       0       0     "\""      0     FIRST_QUOTE      SQL_Latin1_General_CP1_CI_AS
2       SQLCHAR       0       5     "\",\""   1     FNAME               SQL_Latin1_General_CP1_CI_AS
3       SQLCHAR       0       5     "\",\""   2     LNAME            SQL_Latin1_General_CP1_CI_AS
4       SQLCHAR       0       50    "\"\r\n"  3     COMPANY          SQL_Latin1_General_CP1_CI_AS
"col1"|"col2"
"val1"|"val2"
"val3"|"val4"

我也遇到了同样的问题,我不想走SSIS路线,因此我找到了一个易于运行的PowerShell脚本,它可以处理特定字段中带有逗号的引号的情况:

PowerShell脚本的源代码和DLL:

下面是一个解释用法的博客:

确保已启用TextQualified选项并将其设置为

我花了半天时间解决这个问题。最好使用SQL Server导入和导出数据向导进行导入。该向导中有一个解决此问题的设置。此处的详细屏幕截图:谢谢

我知道这是一个老话题,但此功能现在已经从SQL Server 2017年开始实施。您要查找的参数是FIELDQUOTE=,默认为''。请参阅有关被相同参数刺痛的详细信息:)

我将此逻辑包装到一个函数中,以清理已导入的数据

DECLARE @str NVARCHAR(MAX);
DECLARE @quote_identifier NVARCHAR(MAX);

SET @quote_identifier = N'"';

SET @str = N'"quoted stuff"';

SELECT IIF(
           LEFT(@str, 1) = @quote_identifier
           AND RIGHT(@str, 1) = @quote_identifier,
           SUBSTRING(@str, DATALENGTH(@quote_identifier), LEN(@str) - DATALENGTH(@quote_identifier)),
           @str);

我也有同样的问题,但是,它在以下设置下对我有效:

bulk insert schema.table
from '\\your\data\source.csv'
with (
datafiletype = 'char'
,format = 'CSV'
,firstrow = 2
,fieldterminator = '|'
,rowterminator = '\n'
,tablock
)
我的CSV文件如下所示:

select C.ColID, C.[name] as Columnname into #Columns
from syscolumns C
join sysobjects T on C.id = T.id
where T.[name] = 'User_tbl'
order by 1;

declare @QUOTE char(1);
set @QUOTE = Char(39);
select 'Update User_tbl set '+ColumnName+'=replace('+ColumnName+','
 + @QUOTE + '"' + @QUOTE + ',' + @QUOTE + @QUOTE + ');
GO'
from #Columns
where ColID > 2
order by ColID;
9.0
4
1       SQLCHAR       0       0     "\""      0     FIRST_QUOTE      SQL_Latin1_General_CP1_CI_AS
2       SQLCHAR       0       5     "\",\""   1     FNAME               SQL_Latin1_General_CP1_CI_AS
3       SQLCHAR       0       5     "\",\""   2     LNAME            SQL_Latin1_General_CP1_CI_AS
4       SQLCHAR       0       50    "\"\r\n"  3     COMPANY          SQL_Latin1_General_CP1_CI_AS
"col1"|"col2"
"val1"|"val2"
"val3"|"val4"

我的问题是,我以前将行终止符设置为“0x0a”,但它不起作用。一旦我将其更改为“\n”,它就开始起作用了…

我的输入数据中没有多余的引号,只有引用恰好包含逗号的字段所需的引号的确切数量。导入正确引用CSV的数据时,FIELDTERMINATOR是comma和正确的行终止符,大容量导入阻塞的方式表明它不理解引号中的逗号。@EricJ:我理解你的情况。但我不知道Microsoft使用String.Split(,)实现了大容量导入,这是初学者程序员认为CSV工作的方式。微软真可耻。你有两个选择:重新分析CSV并添加额外的引号,然后使用你提到的方法或创建一个程序来生成和执行基于CSV文件的INSERT语句。如果你使用最后一个,请确保你不会对它们进行事务处理。问题是人们不会取消了解如何创建.CSV文件。有两个选项:完全引用(在所有字段周围加引号)或非引用(无引号字段)。之所以产生部分引用CSV文件的想法,是因为Microsoft Excel通常就是这样创建的,但这不是一种有效的格式,除Microsoft Access外,任何数据库引擎都不支持。无法完成。SQL Server导入方法(BCP和大容量插入)不理解引用。这是一篇类似的文章,其中包含更多未正确引用的选项。根据RFC4180,引用应包含所有字段或无字段。部分引用的CSV无效,无法通过批量导入加载。它们可以在Excel、PowerShell甚至OPENROWSET中打开,但不能直接批量导入“@GeoffGriswald我不同意你关于