استيراد SQL بالجملة من CSV

أحتاج إلى استيراد ملف CSV كبير إلى خادم SQL. أنا أستخدم هذا:

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

المشكلة هي أن كل حقولي محاطة بعلامات اقتباس ("") ، لذلك يبدو الصف وكأنه:

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

هل يمكنني استيرادها بشكل جماعي وإخبار SQL باستخدام علامات التنصيص كمحددات الحقل؟

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.

من خلال ما كنت أقرأه ، أعتقد أن FORMATFILE هو الطريق المناسب ، لكن الوثائق (بما في ذلك MSDN) غير مفهومة بشكل رهيب.

0
وأضاف تحرير
الآراء: 1
يجب عليك إعادة وضع علامة على هذا sqlserver حتى نعرف قاعدة البيانات التي تستخدمها.
وأضاف المؤلف JasonS, مصدر

12 إجابة

يجب عليك الانتباه من خلال BCP/BULK INSERT نظرًا لأن BSP أو Bulk Insert لا يعالجان هذا جيدًا إذا كان التسعير غير متسق ، حتى مع ملفات التنسيق (حتى ملفات تنسيق xml لا تقدم الخيار) وأرقام [d] بداية ونهاية واستخدام ["،"] كفاصل. لا تحتاج ملفات CSV من الناحية الفنية إلى ["] أحرف إذا لم تكن هناك حروف مضمنة [،]

ولهذا السبب ، يشار أحيانًا إلى ملفات محددة بفواصل كملفات محدودة خاصة بالكوميديا.

سوف يتطلب OpenRowSet Excel على الخادم ويمكن أن يكون مشكلة في بيئات 64 بت - أعلم أنه من الصعب استخدام Excel في Jet في 64 بت.

SSIS هو حقا أفضل رهان إذا كان من المحتمل أن يختلف الملف عن توقعاتك في المستقبل.

0
وأضاف

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

راجع http://www.sqlteam.com/article/using-bulk-insert-to-load-a-text-file لمزيد من المعلومات.

0
وأضاف

جرب OpenRowSet . يمكن استخدام هذا لاستيراد أشياء Excel. يمكن لـ Excel فتح ملفات CSV ، لذلك تحتاج فقط إلى معرفة القيمة الصحيحة [ConnectionString] [2].

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

0
وأضاف

الاختراق الآخر الذي أستخدمه أحيانًا ، هو فتح ملف CSV في Excel ، ثم كتابة عبارة SQL في خلية في نهاية كل صف. فمثلا:

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

يمكن تعبئة هذا ملء في كل صف لك. ثم فقط قم بنسخ ولصق الإخراج في إطار استعلام جديد.

إنها مدرسة قديمة ، ولكن إذا كنت تحتاج فقط إلى القيام باستيراد مرة واحدة في حين أنها توفر لك العبث بقراءة جميع الوثائق الغامضة على الطريقة "الصحيحة" للقيام بذلك.

0
وأضاف
نصيحة جميلة ،jorgeburgos
وأضاف المؤلف karlgrz, مصدر
أعلم أن هذه الإجابة قديمة ، ولكنني وصلت للتو إلى هنا مع بحث Google عن شيء مشابه. هذا وقت عظيم تريد إنشاء أي رمز من البيانات المجدولة ، وليس فقط رمز لتحميل بيان SQL. يمكنك وضع قالب في مكان ما في ملف Excel ، ثم فعل = SUBSTITUTE ($ Z $ 999 ، "placeholder_a"، "'" & SUBSTITUTE (A2، "'"، "'" ") &" "")، "placeholder_b" ، SUBSTITUTE (B2 ، "'" ، "'" ")) . بافتراض أن لديك نموذجًا بمبلغ 999 دولارًا أمريكيًا (أو ما يعادله بالعملة المحلية).
وأضاف المؤلف Don 01001100, مصدر
نصيحة جيدة ، شكرا!
وأضاف المؤلف DanB, مصدر

هل تحتاج إلى القيام بذلك برمجيًا أم أنها لقطة لمرة واحدة؟

يتيح لك استخدام "إدارة المؤسسة" ، انقر بزر الماوس الأيمن فوق استيراد البيانات تحديد محدد.

0
وأضاف

إذا كنت تفكر في كيفية الحصول على تحليل الملف إلى DataTable ، فأقترح فئة SqlBulkInsert لإدراجه في SQL Server.

0
وأضاف

يمكنك أيضًا استخدام DTS أو SSIS.

0
وأضاف

Try FIELDTERMINATOR='","'

هنا رابط رائع للمساعدة في الاقتباس الأول والأخير ... انظر كيف استخدم سلسلة فرعية SP

http://www.sqlteam.com/article/باستخدام السائبة-إدراج-لتحميل واحد في النص ملف

0
وأضاف
عملت لي كذلك. أستخدم ملف بتنسيق xml لذا تم استخدام سمة Terminator بدلاً من FIELDTERMINATOR. أيضًا ، في العمود الأخير الخاص بي ، استخدمت TERMINATOR = '"\ r \ n"
وأضاف المؤلف Craig McKeachie, مصدر
لن يعمل: --(. الحقل الأول في الجدول هو التاريخ والوقت وسيتم استيراد الاقتباس الرئيسي (") به ، مما يؤدي إلى حدوث خطأ
وأضاف المؤلف Radu094, مصدر
كما يجب الحذر من التطبيقات التي تقوم بتصدير CSV بسلسلة مقتبسة ولكن الأرقام غير مقتبسة.
وأضاف المؤلف finnw, مصدر

هل لديك السيطرة على تنسيق الإدخال؟ | (مواسير) ، و \ t عادةً للحصول على أفضل terminators الحقل.

0
وأضاف

وأنا أعلم أن هذا ليس حلا حقيقيا ولكن يمكنني استخدام جدول وهمية للاستيراد مع مجموعة nvarchar لكل شيء. ثم أقوم بإدخال ما يزيل "الأحرف ويقوم بالتحويلات. إنه ليس جميلاً ولكنه يقوم بهذه المهمة.

0
وأضاف
كيف تقسم الحقول عندما يكون هناك فواصل بين علامات الاقتباس؟
وأضاف المؤلف Jeremy Stein, مصدر

يقول Id استخدم FileHelpers في مكتبة مفتوحة المصدر

0
وأضاف

التنوب الذي تحتاجه لاستيراد ملف 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);
                }
            }
        }
    }
}
0
وأضاف