在 SQL Server 2008 中批量插入 Unicode 文本会导致“意外的文件结尾”

问题描述 投票:0回答:1

我正在尝试创建一个脚本,使用之前保存在 Excel 中的 unicode 文本来更新表格。

我的 SQL Server 版本是:

Microsoft SQL Server 2008 R2 (SP1) - 10.50.2500.0 (X64)   
Copyright (c) Microsoft Corporation  Standard Edition (64-bit) on Windows NT 6.2 \<X64\> (Build 9200: )

表格创建如下:

CREATE TABLE ActualizarMasiva
(
    [barra] [varchar](150) NOT NULL,
    [articulo] [varchar](150) NULL,
    [und] [decimal](28, 0) NULL,
    [costo] [float] NULL,
    [precio1] [float] NULL,
    [margen1] [float] NULL,
    [precio4] [float] NULL,
    [margen4] [float] NULL,
    tipo_imp [varchar](50) NULL,
    [capacidad] [float] NULL,
    tipo_licor [varchar](50) NULL,
    grado_al [decimal](10,2) NULL
) ON [PRIMARY]

请注意,除了第一列之外,任何列都可以为空,并且即使按照此建议

,数据较小,我也使用了
varchar(50)

我有一个格式文件,其中包含以下信息:

Format specifying the format and lenghts

我已阅读 Microsoft 的这些文章:

使用BULK INSERT和XML格式文件

非XML格式文件的结构

指定字段和行终止符 (SQL Server)

这是运行批量插入后的错误消息:

日志说:

第 39 行文件偏移量 7415 错误文件偏移量 0 - HRESULT 0x80004005

但是第 39 行的格式与其他行相同,因此我并没有真正看到错误本身。

我尝试过使用 ROWTERMINATOR = ' ' 或者 ' '以及这两者的任意组合。我还尝试更改前缀长度并使用 Null 终止符(如果是这种情况)。我还用 Notepad++ 检查过,这是它的打印结果:

这是批量插入脚本:

BULK INSERT ActualizarMasiva FROM 'C:\Users\Administrador\Documents\CSV corrida masiva\actualizarmasivaprueba.txt' WITH ( FIRSTROW = 2, --Contiene headers DATAFILETYPE = 'char', FORMATFILE = 'C:\Users\Administrador\Documents\CSV corrida masiva\FormatoActualizacionMasiva.fmt', ERRORFILE = 'C:\Users\Administrador\Documents\CSV corrida masiva\errorLog' );
也许我错过了一些东西,但现在我还没有看到它。

sql-server windows csv bulk
1个回答
0
投票
我找到了解决问题的方法。我是这样做的:

背景

@AlwaysLerning 评论给了我一些尝试的想法,包括将 Unicode 更改为 UFT-8,但这根本没有帮助。所以我尝试

not使用格式文件来指定变量的列和类型。我第一次尝试时没有使用它的原因是因为我想将类型从 varchar 更改为 float。

解决方案如下:

CREATE TABLE ActualizarMasiva( [barra] [varchar](150) NOT NULL, [articulo] [varchar](150) NULL, [und] [decimal](28, 0) NULL, [costo] [float] NULL, [precio1] [float] NULL, [margen1] [float] NULL, [precio4] [float] NULL, [margen4] [float] NULL, tipo_imp [varchar](50) NULL, [capacidad][float] NULL, tipo_licor [varchar](50) NULL, grado_al [decimal](10,2) NULL ) ON [PRIMARY] GO CREATE TABLE ActualizarMasivaIni( [barra] [nvarchar](150) NOT NULL, [articulo] [nvarchar](150) NULL, [und] [nvarchar](150) NULL, [costo] [nvarchar](150) NULL, [precio1] [nvarchar](150) NULL, [margen1] [nvarchar](150) NULL, [precio4] [nvarchar](150) NULL, [margen4] [nvarchar](150) NULL, tipo_imp [nvarchar](150) NULL, [capacidad] [nvarchar](150) NULL, tipo_licor [nvarchar](150) NULL, grado_al [nvarchar](150) NULL ) ON [PRIMARY] GO BULK INSERT ActualizarMasivaIni FROM 'C:\Users\Administrador\Documents\CSV corrida masiva\actualizarmasiva.txt' WITH ( DATAFILETYPE = 'widechar', FIELDTERMINATOR = '\t', FIRSTROW = 2, MAXERRORS = 0, ROWTERMINATOR = '\n' ,ERRORFILE = 'C:\Users\Administrador\Documents\CSV corrida masiva\errorLog' ) ; INSERT INTO actualizarmasiva (Barra,articulo,und,costo,Precio1,Margen1,Precio4,Margen4,Tipo_imp,[Capacidad],tipo_licor,grado_al) SELECT Barra ,articulo ,und ,cast(replace(costo,',','.') as float) ,cast(replace(Precio1,',','.') as float) ,cast(replace(Margen1,',','.') as float) ,cast(replace(Precio1,',','.') as float) ,cast(replace(Margen4,',','.') as float) ,cast(replace(Tipo_imp,',','.') as int) ,cast(replace([Capacidad],',','.') as float) ,tipo_licor ,cast(replace(grado_al,',','.') as float) FROM actualizarmasivaIni

说明: 我可以将数据导入为 nvarchar,而无需在辅助表中进行转换,然后在将要使用的表中插入行时进行转换。这样您就可以将数据类型转换留在服务器内部,而不是 BULK INSERT 函数。

我确信有一个更详细的解释,说明为什么即使使用“widechar”参数也不能使用 Unicode 和批量插入,但这个解决方案不需要太多的努力,结果是理想的。

只要辅助表不是太大,我认为这对于此类导入来说是一个可行的选择。

© www.soinside.com 2019 - 2024. All rights reserved.