从 CSV SQL 批量导入

发布于 2024-07-06 07:49:31 字数 612 浏览 7 评论 0原文

我需要将大型 CSV 文件导入 SQL 服务器。 我正在使用这个:

BULK 
INSERT CSVTest
        FROM 'c:\csvfile.txt'
            WITH
    (
                FIELDTERMINATOR = ',',
                ROWTERMINATOR = '\n'
    )
GO

问题是我的所有字段都被引号(“”)包围,所以一行实际上看起来像:

"1","","2","","sometimes with comma , inside", "" 

我可以以某种方式批量导入它们并告诉 SQL 使用引号作为字段分隔符吗?

编辑:使用 '","' 作为分隔符的问题(如示例中建议的那样)是: 大多数示例所做的就是导入数据,包括第一列中的第一个“和最后一列中的最后一个”,然后继续将其删除。 唉,我的第一列(也是最后一列)是日期时间,并且不允许将“20080902 作为日期时间导入。

根据我一直在阅读的内容,我认为 FORMATFILE 是可行的方法,但文档(包括 MSDN)非常无用。

I need to import a large CSV file into an SQL server. I'm using this :

BULK 
INSERT CSVTest
        FROM 'c:\csvfile.txt'
            WITH
    (
                FIELDTERMINATOR = ',',
                ROWTERMINATOR = '\n'
    )
GO

problem is all my fields are surrounded by quotes (" ") so a row actually looks like :

"1","","2","","sometimes with comma , inside", "" 

Can I somehow bulk import them and tell SQL to use the quotes as field delimiters?

Edit: The problem with using '","' as delimiter, as in the examples suggested is that :
What most examples do, is they import the data including the first " in the first column and the last " in the last, then they go ahead and strip that out. Alas my first (and last) column are datetime and will not allow a "20080902 to be imported as datetime.

From what I've been reading arround I think FORMATFILE is the way to go, but documentation (including MSDN) is terribly unhelpfull.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(14

深海蓝天 2024-07-13 07:49:31

尝试 FIELDTERMINATOR='","'

这是一个很好的链接,可以帮助您处理第一个和最后一个引号...看看他如何使用 SP

http://www.sqlteam.com/article/using-bulk-insert-to-load-文本文件

Try FIELDTERMINATOR='","'

Here is a great link to help with the first and last quote...look how he used the substring the SP

http://www.sqlteam.com/article/using-bulk-insert-to-load-a-text-file

芯好空 2024-07-13 07:49:31

我有时使用的另一个技巧是在 Excel 中打开 CSV,然后将 sql 语句写入每行末尾的单元格中。
例如:

=concatenate("insert into myTable (columnA,columnB) values ('",a1,"','",b1,"'")")

填充可以将其填充到每一行中。 然后只需将输出复制并粘贴到新的查询窗口中即可。

这是老派的做法,但如果您只需要偶尔进行一次导入,那么您就可以不用花时间阅读所有有关“正确”方法的晦涩文档。

Another hack which I sometimes use, is to open the CSV in Excel, then write your sql statement into a cell at the end of each row.
For example:

=concatenate("insert into myTable (columnA,columnB) values ('",a1,"','",b1,"'")")

A fill-down can populate this into every row for you. Then just copy and paste the output into a new query window.

It's old-school, but if you only need to do imports once in a while it saves you messing around with reading all the obscure documentation on the 'proper' way to do it.

执笏见 2024-07-13 07:49:31

尝试 OpenRowSet。 这可用于导入 Excel 内容。 Excel可以打开CSV文件,因此您只需找出正确的[ConnectionString][2]即可。

[2]: Driver={Microsoft Text Driver (*.txt; *.csv)};Dbq=c:\txtFilesFolder\;Extensions=asc,csv,tab,txt;

Try OpenRowSet. This can be used to import Excel stuff. Excel can open CSV files, so you only need to figure out the correct [ConnectionString][2].

[2]: Driver={Microsoft Text Driver (*.txt; *.csv)};Dbq=c:\txtFilesFolder\;Extensions=asc,csv,tab,txt;

眸中客 2024-07-13 07:49:31

我知道这不是一个真正的解决方案,但我使用一个虚拟表进行导入,并为所有内容设置了 nvarchar 。 然后我做了一个插入,去掉了 " 字符并进行转换。它不漂亮,但它完成了工作。

I know this isn't a real solution but I use a dummy table for the import with nvarchar set for everything. Then I do an insert which strips out the " characters and does the conversions. It isn't pretty but it does the job.

如梦初醒的夏天 2024-07-13 07:49:31

我想说使用 FileHelpers 它是一个开源库

Id say use FileHelpers its an open source library

眼趣 2024-07-13 07:49:31

您是否需要以编程方式执行此操作,还是一次性执行?

使用企业管理器,右键单击“导入数据”可以选择分隔符。

Do you need to do this programmatically, or is it a one-time shot?

Using the Enterprise Manager, right-click Import Data lets you select your delimiter.

鸩远一方 2024-07-13 07:49:31

您必须注意 BCP/BULK INSERT,因为如果引用不一致,BSP 或批量插入都无法很好地处理此问题,即使使用格式文件(甚至 XML 格式文件也不提供该选项)和虚拟 ["] 字符开始和结束并使用 [","] 作为分隔符 从技术上讲,如果没有嵌入的 [,] 字符,CSV 文件不需要包含 ["] 字符。

因此,逗号分隔文件有时被称为。喜剧限制文件。

OpenRowSet 需要服务器上有 Excel,并且在 64 位环境中可能会出现问题 - 我知道在 64 位环境中使用 Jet 中的 Excel 会出现问题。

如果文件将来可能与您的预期有所不同,SSIS 确实是您最好的选择。

You have to watch out with BCP/BULK INSERT because neither BSP or Bulk Insert handle this well if the quoting is not consistent, even with format files (even XML format files don't offer the option) and dummy ["] characters at the beginning and end and using [","] as the separator. Technically CSV files do not need to have ["] characters if there are no embedded [,] characters

It is for this reason that comma-delimited files are sometimes referred to as comedy-limited files.

OpenRowSet will require Excel on the server and could be problematic in 64-bit environments - I know it's problematic using Excel in Jet in 64-bit.

SSIS is really your best bet if the file is likely to vary from your expectations in the future.

木有鱼丸 2024-07-13 07:49:31

如果你愿意的话,你可以尝试这个非常甜蜜的代码,
这将从代码中删除不需要的分号。
例如,如果您的数据是这样的:
"Kelly","Reynold"," [电子邮件受保护]

Bulk insert test1
from 'c:\1.txt' with ( 
    fieldterminator ='","'
    ,rowterminator='\n')

update test1<br>
set name =Substring (name , 2,len(name))
where name like **' "% '**

update test1
set email=substring(email, 1,len(email)-1)
where email like **' %" '**

u can try this code which is very sweet if you want ,
this will remove unwanted semicolons from your code.
if for example your data is like this :
"Kelly","Reynold","[email protected]"

Bulk insert test1
from 'c:\1.txt' with ( 
    fieldterminator ='","'
    ,rowterminator='\n')

update test1<br>
set name =Substring (name , 2,len(name))
where name like **' "% '**

update test1
set email=substring(email, 1,len(email)-1)
where email like **' %" '**
雨的味道风的声音 2024-07-13 07:49:31

首先您需要将 CSV 文件导入数据表

然后您可以使用 SQLBulkCopy 插入批量行

using System;
using System.Data;
using System.Data.SqlClient;

namespace SqlBulkInsertExample
{
    class Program
    {
      static void Main(string[] args)
        {
            DataTable prodSalesData = new DataTable("ProductSalesData");

            // Create Column 1: SaleDate
            DataColumn dateColumn = new DataColumn();
            dateColumn.DataType = Type.GetType("System.DateTime");
            dateColumn.ColumnName = "SaleDate";

            // Create Column 2: ProductName
            DataColumn productNameColumn = new DataColumn();
            productNameColumn.ColumnName = "ProductName";

            // Create Column 3: TotalSales
            DataColumn totalSalesColumn = new DataColumn();
            totalSalesColumn.DataType = Type.GetType("System.Int32");
            totalSalesColumn.ColumnName = "TotalSales";

            // Add the columns to the ProductSalesData DataTable
            prodSalesData.Columns.Add(dateColumn);
            prodSalesData.Columns.Add(productNameColumn);
            prodSalesData.Columns.Add(totalSalesColumn);

            // Let's populate the datatable with our stats.
            // You can add as many rows as you want here!

            // Create a new row
            DataRow dailyProductSalesRow = prodSalesData.NewRow();
            dailyProductSalesRow["SaleDate"] = DateTime.Now.Date;
            dailyProductSalesRow["ProductName"] = "Nike";
            dailyProductSalesRow["TotalSales"] = 10;

            // Add the row to the ProductSalesData DataTable
            prodSalesData.Rows.Add(dailyProductSalesRow);

            // Copy the DataTable to SQL Server using SqlBulkCopy
            using (SqlConnection dbConnection = new SqlConnection("Data Source=ProductHost;Initial Catalog=dbProduct;Integrated Security=SSPI;Connection Timeout=60;Min Pool Size=2;Max Pool Size=20;"))
            {
                dbConnection.Open();
                using (SqlBulkCopy s = new SqlBulkCopy(dbConnection))
                {
                    s.DestinationTableName = prodSalesData.TableName;

                    foreach (var column in prodSalesData.Columns)
                        s.ColumnMappings.Add(column.ToString(), column.ToString());

                    s.WriteToServer(prodSalesData);
                }
            }
        }
    }
}

Firs you need to import CSV file into Data Table

Then you can insert bulk rows using SQLBulkCopy

using System;
using System.Data;
using System.Data.SqlClient;

namespace SqlBulkInsertExample
{
    class Program
    {
      static void Main(string[] args)
        {
            DataTable prodSalesData = new DataTable("ProductSalesData");

            // Create Column 1: SaleDate
            DataColumn dateColumn = new DataColumn();
            dateColumn.DataType = Type.GetType("System.DateTime");
            dateColumn.ColumnName = "SaleDate";

            // Create Column 2: ProductName
            DataColumn productNameColumn = new DataColumn();
            productNameColumn.ColumnName = "ProductName";

            // Create Column 3: TotalSales
            DataColumn totalSalesColumn = new DataColumn();
            totalSalesColumn.DataType = Type.GetType("System.Int32");
            totalSalesColumn.ColumnName = "TotalSales";

            // Add the columns to the ProductSalesData DataTable
            prodSalesData.Columns.Add(dateColumn);
            prodSalesData.Columns.Add(productNameColumn);
            prodSalesData.Columns.Add(totalSalesColumn);

            // Let's populate the datatable with our stats.
            // You can add as many rows as you want here!

            // Create a new row
            DataRow dailyProductSalesRow = prodSalesData.NewRow();
            dailyProductSalesRow["SaleDate"] = DateTime.Now.Date;
            dailyProductSalesRow["ProductName"] = "Nike";
            dailyProductSalesRow["TotalSales"] = 10;

            // Add the row to the ProductSalesData DataTable
            prodSalesData.Rows.Add(dailyProductSalesRow);

            // Copy the DataTable to SQL Server using SqlBulkCopy
            using (SqlConnection dbConnection = new SqlConnection("Data Source=ProductHost;Initial Catalog=dbProduct;Integrated Security=SSPI;Connection Timeout=60;Min Pool Size=2;Max Pool Size=20;"))
            {
                dbConnection.Open();
                using (SqlBulkCopy s = new SqlBulkCopy(dbConnection))
                {
                    s.DestinationTableName = prodSalesData.TableName;

                    foreach (var column in prodSalesData.Columns)
                        s.ColumnMappings.Add(column.ToString(), column.ToString());

                    s.WriteToServer(prodSalesData);
                }
            }
        }
    }
}
滥情哥ㄟ 2024-07-13 07:49:31

这是一个老问题,所以我写这篇文章是为了帮助任何偶然发现它的人。

SQL Server 2017 引入了FIELDQUOTE 参数,该参数正是针对这种用例。

This is an old question, so I write this to help anyone who stumble upon it.

SQL Server 2017 introduces the FIELDQUOTE parameter which is intended for this exact use case.

梦回梦里 2024-07-13 07:49:31

是的,K Richard 是对的:FIELDTERMINATOR = '","'

请参阅http://www.sqlteam.com/article/using-bulk-insert-to-load-a-text-file 了解更多信息。

Yup, K Richard is right: FIELDTERMINATOR = '","'

See http://www.sqlteam.com/article/using-bulk-insert-to-load-a-text-file for more info.

静若繁花 2024-07-13 07:49:31

您还可以使用 DTS 或 SSIS。

You could also use DTS or SSIS.

一曲琵琶半遮面シ 2024-07-13 07:49:31

您可以控制输入格式吗? | (管道)和 \t 通常可以提供更好的字段终止符。

Do you have control over the input format? | (pipes), and \t usually make for better field terminators.

烟火散人牵绊 2024-07-13 07:49:31

如果您弄清楚如何将文件解析为 DataTable,我建议使用 SqlBulkInsert 类将其插入 SQL Server。

If you figure out how to get the file parsed into a DataTable, I'd suggest the SqlBulkInsert class for inserting it into SQL Server.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文