Question

I'm trying to dump a very large set of data from a .csv file into a SQL Server 2012 database. Rather than doing thousands of INSERTs, I'm investigating bcp.

EDIT: This is for an automated process, and not just a one-off. I also do not have BULK INSERT rights to this database.

When I try to copy data into the database, bcp doesn't return any errors, but also doesn't actually copy anything - it just returns 0 rows copied. I've whittled this down to a minimal case that doesn't work.

First, create a simple table with two columns:

CREATE TABLE [dbo].[mincase](
    [key] [varchar](36) NOT NULL,
    [number] [int] NOT NULL

    PRIMARY KEY CLUSTERED 
    (
        [key] ASC
    )
    WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON, FILLFACTOR = 40) ON [PRIMARY]
) ON [PRIMARY]

GO

Then, use bcp to create a format file from this. Note that this example creates an XML format file, but it doesn't matter whether it's XML or native for this.

bcp MyDB.dbo.mincase format nul -T -n -f mincasexml.fmt -x -S .\SQLEXPRESS

Now create a data.csv file with one row and two entries, tab-delimited. In my case, the file is simply:

somecharacters  12345

Again, that's a tab, not two spaces, and it doesn't seem to matter whether there are trailing newlines or not.

Now try to use bcp with that format file to insert the data from this file:

bcp MyDB.dbo.mincase in data.csv -f mincasexml.fmt -T -S .\SQLEXPRESS

Rather than copying data to the database, I get this:

Starting copy...

0 rows copied.
Network packet size (bytes): 4096
Clock Time (ms.) Total     : 1

Does anyone know what's going on here?

Thanks!

Was it helpful?

Solution

The bcp command typically needs an identifier to specify the format mode of the bcp file.

  • -c specifies character (plaintext) mode
  • -n specifies native mode
  • -w specifies unicode mode

In your test case, the file you created is plaintext, so you should specify '-c' in your bcp in command.

bcp MyDB.dbo.mincase in data.csv -c -T -S .\SQLEXPRESS

Microsoft Recommends using the '-n' for imports and exports to avoid issues with field delimiters appearing within column values (See section on Character Mode and Native Mode Best Practices).

OTHER TIPS

I ran into a similar issue, except that I was already using a format file, so adding one of the format flags wouldn't help. For anyone else who ends up here, I want to explain what caused this issue for me (and hopefully help explain what the underlying issue cause is).

The issue is that BCP doesn't actually process lines of text in a file; rather, it just processes a stream of data, according to the instructions you give it. This means that newlines will be ignored, if that's what you (accidentally) tell BCP to do.

In my case, this turned out to be a typo in the last line in the format file:

13.0
1348
1 SQLCHAR 0 21 "," 1 RecordKey ""
2 SQLCHAR 0 30 "," 0 SubmissionKey ""
3 SQLCHAR 0 1 "," 2 A1cLvl ""
...
1347 SQLCHAR 0 1 "," 0 WoundIntVac ""
1348 SQLCHAR 0 1 "/r/n" 0 XClampTm ""

If you look closely, you'll see the slashes are backwards in the terminator field on the last line. So, instead of looking for Windows-style line endings, BCP was actually looking for the text string "/r/n" in the data stream.

Since the string didn't actually appear in my data at all, BCP never actually found anything matching my final field. So, it makes sense that it found "0 rows" to copy.

I'm still not sure why this doesn't result in something like an "Unexpected EOF encountered" error or something, but hopefully someone else will be able to expand on this.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top