合并来自txt文件的数据,每个列具有特定的位置和长度

时间:2013-09-14 17:20:15

标签: sql sql-server merge

我试图将txt文件的内容与特定位置合并,并使用表格为每列进行长度合并。

Example: From Position: 1  to Position: 7   = Col_1
         From Position: 8  to position: 21  = Col_2
         From Position: 22 to Position: 47  = Col_3

我正在使用CAST(Substring(colum_Name,from_position, to_position) AS data_type) AS colum_name, 格式化

在合并脚本中,我都准备好为每列设置固定的长度和位置。

这就是我想要做的事情。

创建一个只有一列的表。

CREATE TABLE camposSinFormato(String VARCHAR(255)) 
GO  

然后,BULK将没有格式的txt内容插入该列。

BULK INSERT camposSinFormato
FROM 'F:\genera\completo\STK-TOTAL.TXT'
WITH(
    ROWTERMINATOR = '\n'
    );
GO

现在,我根据需要使用merge来插入或更新表。

我的问题是,为了这样做,我必须使用CAST(SUBSTRING在更新/插入之前格式化数据,我认为我做错了。

这是我合并代码的示例。

BEGIN TRAN;
    MERGE productos AS T
    USING camposSinFormato AS S
    ON (T.nroTroquel = S.nroTroquel) 
    WHEN NOT MATCHED BY TARGET  
        THEN INSERT(
                    T.nroTroquel, 
                    T.nombre,
                    T.idlaboratorio,
                    T.precio, 
                    T.iva,
                    T.codigobarras,
                    T.tipoProducto,
                    T.subtipoProducto,
                    T.esRefrigerado
                    ) 
                VALUES 
                   (
                   CAST(SUBSTRING(S.String, 1, 7)AS BIGINT, PRIMARY KEY) AS nroTroquel,                     
                   CAST(SUBSTRING(S.String, 8, 21)AS VARCHAR(50) NOT NULL)AS nombre,                        
                   CAST(SUBSTRING(S.String, 22, 47)AS INT NOT NULL) as idlaboratorio,                       
                   CAST(SUBSTRING(S.String, 48, 62)AS MONEY NULL) as precio,                                
                   CAST(SUBSTRING(S.String, 63, 78)AS INT NULL) as iva,                                 
                   CAST(SUBSTRING(S.String, 79, 80)AS VARCHAR(13) NULL) as codigobarras,                
                   CAST(SUBSTRING(S.String, 81, 82)AS VARCHAR(14) NULL) as tipoProducto,                
                   CAST(SUBSTRING(S.String, 83, 84)AS VARCHAR(15) NULL) as subTipoProducto,             
                   CAST(SUBSTRING(S.String, 85, 91)AS BIT NULL) as esRefrigerado
                   )
        WHEN MATCHED 
        THEN UPDATE 
                SET T.nombre = CAST(SUBSTRING(String, 8, 21)AS VARCHAR(50) NOT NULL)AS nombre,
                    T.idlaboratorio = CAST(SUBSTRING(String, 22, 47)AS INT NOT NULL) as idlaboratorio,
                    T.iva = CAST(SUBSTRING(String, 63, 78)AS INT NULL) as iva,  
                    T.codigobarras = CAST(SUBSTRING(String, 79, 80)AS VARCHAR(13) NULL) as codigobarras,
                    T.tipoProducto =  CAST(SUBSTRING(String, 81, 82)AS VARCHAR(14) NULL) as tipoProducto,
                    T.subtipoProducto = CAST(SUBSTRING(String, 83, 84)AS VARCHAR(15) NULL) as subTipoProducto,
                    T.esRefrigerado = CAST(SUBSTRING(String, 85, 91)AS BIT NULL) as esRefrigerado       

        WHERE S.nroTroquel = T.nroTroquel

    OUTPUT $action, updated, inserted.*;

任何人都可以告诉我这样做的方式是否正确?

提前致谢。

P.S:对于编辑感到抱歉,我在原文中解释错了

1 个答案:

答案 0 :(得分:1)

我不会说你不对,但我认为这个过程可以改进。如果space是分隔符,则更改BULK INSERT以将FIELDTERMINATOR指定为空格。例如。

BULK INSERT camposSinFormato
FROM 'F:\genera\completo\STK-TOTAL.TXT'
WITH(
    FIELDTERMINATOR = ' ',
    ROWTERMINATOR = '\n'
    );
GO

您需要正确定义camposSinFormato(即,而不是单个列,您需要指定所有列)。