BULK INSERT with identity (auto-increment) column

前端 未结 9 1291
情话喂你
情话喂你 2020-11-29 02:57

I am trying to add bulk data in database from CSV file.

Employee table has a column ID (PK) auto-incremented.

CREATE TABLE [dbo].[Employ         


        
相关标签:
9条回答
  • 2020-11-29 03:38

    This is a very old post to answer, but none of the answers given solves the problem without changing the posed conditions, which I can't do.

    I solved it by using the OPENROWSET variant of BULK INSERT. This uses the same format file and works in the same way, but it allows the data file be read with a SELECT statement.

    Create your table:

    CREATE TABLE target_table(
    id bigint IDENTITY(1,1),
    col1 varchar(256) NULL,
    col2 varchar(256) NULL,
    col3 varchar(256) NULL)
    

    Open a command window an run:

    bcp dbname.dbo.target_table format nul -c -x -f C:\format_file.xml -t; -T
    

    This creates the format file based on how the table looks.

    Now edit the format file and remove the entire rows where FIELD ID="1" and COLUMN SOURCE="1", since this does not exist in our data file.
    Also adjust terminators as may be needed for your data file:

    <?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="2" xsi:type="CharTerm" TERMINATOR=";" MAX_LENGTH="256" COLLATION="Finnish_Swedish_CI_AS"/>
      <FIELD ID="3" xsi:type="CharTerm" TERMINATOR=";" MAX_LENGTH="256" COLLATION="Finnish_Swedish_CI_AS"/>
      <FIELD ID="4" xsi:type="CharTerm" TERMINATOR="\r\n" MAX_LENGTH="256" COLLATION="Finnish_Swedish_CI_AS"/>
     </RECORD>
     <ROW>
      <COLUMN SOURCE="2" NAME="col1" xsi:type="SQLVARYCHAR"/>
      <COLUMN SOURCE="3" NAME="col2" xsi:type="SQLVARYCHAR"/>
      <COLUMN SOURCE="4" NAME="col3" xsi:type="SQLVARYCHAR"/>
     </ROW>
    </BCPFORMAT>
    

    Now we can bulk load the data file into our table with a select, thus having full controll over the columns, in this case by not inserting data into the identity column:

    INSERT INTO target_table (col1,col2, col3)
    SELECT * FROM  openrowset(
    bulk 'C:\data_file.txt',
    formatfile='C:\format_file.xml') as t;
    
    0 讨论(0)
  • 2020-11-29 03:41

    I had a similar issue, but I needed to be sure that the order of the ID is aligning to the order in the source file. My solution is using a VIEW for the BULK INSERT:

    Keep your table as it is and create this VIEW (select everything except the ID column)

    CREATE VIEW [dbo].[VW_Employee]
    AS
    SELECT [Name], [Address]
    FROM [dbo].[Employee];
    

    Your BULK INSERT should then look like:

    BULK INSERT [dbo].[VW_Employee] FROM 'path\tempFile.csv ' 
    WITH (FIRSTROW = 2,FIELDTERMINATOR = ',' , ROWTERMINATOR = '\n');
    
    0 讨论(0)
  • 2020-11-29 03:44

    My solution is to add the ID field as the LAST field in the table, thus bulk insert ignores it and it gets automatic values. Clean and simple ...

    For instance, if inserting into a temp table:

    CREATE TABLE #TempTable 
    (field1 varchar(max), field2 varchar(max), ... 
    ROW_ID int IDENTITY(1,1) NOT NULL)
    

    Note that the ROW_ID field MUST always be specified as LAST field!

    0 讨论(0)
  • 2020-11-29 03:45
    1. Create a table with Identity column + other columns;
    2. Create a view over it and expose only the columns you will bulk insert;
    3. BCP in the view
    0 讨论(0)
  • 2020-11-29 03:47

    I had this exact same problem which made loss hours so i'm inspired to share my findings and solutions that worked for me.

    1. Use an excel file

    This is the approach I adopted. Instead of using a csv file, I used an excel file (.xlsx) with content like below.

    id  username   email                token website
    
        johndoe   johndoe@divostar.com        divostar.com
        bobstone  bobstone@divosays.com        divosays.com
    

    Notice that the id column has no value.

    Next, connect to your DB using Microsoft SQL Server Management Studio and right click on your database and select import data (submenu under task). Select Microsoft Excel as source. When you arrive at the stage called "Select Source Tables and Views", click edit mappings. For id column under destination, click on it and select ignore . Don't check Enable Identity insert unless you want to mantain ids incases where you are importing data from another database and would like to maintain the auto increment id of the source db. Proceed to finish and that's it. Your data will be imported smoothly.

    2. Using CSV file

    In your csv file, make sure your data is like below.

    id,username,email,token,website
    ,johndoe,johndoe@divostar.com,,divostar.com
    ,bobstone,bobstone@divosays.com,,divosays.com
    

    Run the query below:

    BULK INSERT Metrics FROM 'D:\Data Management\Data\CSV2\Production Data 2004 - 2016.csv '
    WITH (FIRSTROW = 2, FIELDTERMINATOR = ',', ROWTERMINATOR = '\n');
    

    The problem with this approach is that the CSV should be in the DB server or some shared folder that the DB can have access to otherwise you may get error like "Cannot opened file. The operating system returned error code 21 (The device is not ready)".

    If you are connecting to a remote database, then you can upload your CSV to a directory on that server and reference the path in bulk insert.

    3. Using CSV file and Microsoft SQL Server Management Studio import option

    Launch your import data like in the first approach. For source, select Flat file Source and browse for your CSV file. Make sure the right menu (General, Columns, Advanced, Preview) are ok. Make sure to set the right delimiter under columns menu (Column delimiter). Just like in the excel approach above, click edit mappings. For id column under destination, click on it and select ignore .

    Proceed to finish and that's it. Your data will be imported smoothly.

    0 讨论(0)
  • 2020-11-29 03:52

    You have to do bulk insert with format file:

       BULK INSERT Employee FROM 'path\tempFile.csv ' 
       WITH (FORMATFILE = 'path\tempFile.fmt');
    

    where format file (tempFile.fmt) looks like this:

    11.0
    2
    1 SQLCHAR 0 50 "\t"  2  Name   SQL_Latin1_General_CP1_CI_AS
    2 SQLCHAR 0 50 "\r\n" 3  Address  SQL_Latin1_General_CP1_CI_AS

    more details here - http://msdn.microsoft.com/en-us/library/ms179250.aspx

    0 讨论(0)
提交回复
热议问题