带有ID主键的SQL Server中的BCP移位值

时间:2017-09-29 15:01:56

标签: sql-server bcp

我使用bcp.csv文件导入SQL Server中的表,如下所示:

bcp test1 in "./file.csv" -S server_name -U login_id -P password -d database_name -c -t

我收到此消息/警告:

  

BCP数据文件中遇到意外的EOF   bcp copy in failed

file.csv数据:

A, B, C
A, B, C
A, B, C
A, B, C

我的桌子:

CREATE TABLE test2
(
    a VARCHAR(8) PRIMARY KEY,
    b VARCHAR(8),
    c VARCHAR(8)
);

CREATE TABLE test1 
(
    ID INT NOT NULL IDENTITY(1,1) PRIMARY KEY,
    a VARCHAR(8),
    b VARCHAR(8),
    c VARCHAR(8)

    FOREIGN KEY (a) REFERENCES test2(a)
);

以下是我在SELECT * FROM test1;中的内容:

ID | a | b |   c   |
1    B   CA B    C
A    B   CA B    C

这是我的预期:

ID|a |b |c
1  A  B  C
2  A  B  C
3  A  B  C
3  A  B  C

我与test2没有任何问题,几乎与test相似但没有ID。因此csv文件格式正确。那么为什么我会这样转变?

编辑1

如果我向csv个文件添加标题,请在SELECT * FROM test1

中添加此标题
ID|a|b|c                        |
1  b cA B,C,A,B,C,A,B,C,A,B,C

编辑2

我生成了一个File Format来指导我的数据。

13.0
3
1    SQLCHQR    0    40    "\t"    1    a    SQL_Latin1_General_CP1_CI_AS
2    SQLCHQR    0    40    "\t"    2    a    SQL_Latin1_General_CP1_CI_AS
3    SQLCHQR    0    40    "\t"    3    a    SQL_Latin1_General_CP1_CI_AS

修改后的那个试图"跳跃"超过ID

13.0
4
1    SQLCHQR    0    40    "\t"    2    a    SQL_Latin1_General_CP1_CI_AS
2    SQLCHQR    0    40    "\t"    3    a    SQL_Latin1_General_CP1_CI_AS
3    SQLCHQR    0    40    "\t"    4    a    SQL_Latin1_General_CP1_CI_AS

但我无法使其发挥作用。

bcp test1 in "./file.csv" -S server_name -U login_id -P password -d database_name -f file_name -t
  

SQLState = S1002,NativeError = 0   错误= [Microsoft] [ODBC SQL Server驱动程序]无效的描述符索引

编辑3

我找到了解决问题的方法,但它仍然不是一个好的解决方案。我做的是: 更改我的test1表,将ID列放在最后。 然后在我的CSV中每行的末尾添加sed双逗号以创建新的空列。然后我做了一个简单的bcp in。我仍然希望在第一列中保留ID,我只是不想创建额外的View以便将ID放在前面。

1 个答案:

答案 0 :(得分:0)

由于-E开关

的反义,

首次修改

您错过了-E的{​​{1}},知道您正在尝试使用“身份”列。

如果使用此开关,则会从文件中获取值,并忽略SQL Server标识值。您之后应该预先BCP

第二次修改,因为用户提示更具体。

编辑@BeGreen后指定他想使用DBCC CHECKIDENT('table_name', RESEED)。我将发布示例如何做到这一点。我不需要在Stack溢出的其他帖子中看到前面的视图:What will be BCP format for inserting a identity column

示例不一致,因为CSV正在混合format file(在示例中)和","(在格式表中)。我将在示例中仅使用"\t"

这是可能的,但你必须使用正确的方法。

首先,您必须通过此命令生成格式文件:

","

然后你在这种情况下使用生成的bcp <db_name>.dbo.test1 format nul -c -f "generated_format_file.fmt" -t "," -S "<server>\<instance>" -T 文件(使用SQL Server 2005 - 因为我有快速测试实例 - 你可以改变第一个数字以满足你的需要,例如13.0):

.fmt

8.0 4 1 SQLCHAR 0 12 "," 1 ID "" 2 SQLCHAR 0 8 "," 2 a SQL_Latin1_General_CP1_CI_AS 3 SQLCHAR 0 8 "," 3 b SQL_Latin1_General_CP1_CI_AS 4 SQLCHAR 0 8 "\r\n" 4 c SQL_Latin1_General_CP1_CI_AS 文件看起来(我已经添加了测试ID,而不是应该插入表中的Identity值):

*.csv

然后输入正确的命令(注意:使用受信任的连接10,A1,B1,C1 20,A2,B2,C2 30,A3,B3,C3 40,A4,B4,C4 而不是-T -U来缩短线路:

-P

数据导入为(test1):

bcp <db_name>.<schema>.test1 IN "import_data.bcp" -f "generated_format_file.fmt" -t "," -S "<server>\<instance>" -T

Starting copy...

4 rows copied.
Network packet size (bytes): 4096
Clock Time (ms.) Total     : 218    Average : (18.35 rows per sec.)

要检查当前处于test1的身份值:

ID  a   b   c
1   A1  B1  C1
2   A2  B2  C2
3   A3  B3  C3
4   A4  B4  C4

结果:

select IDENT_CURRENT('[database_name].[dbo].[test1]')