Sqlserver
 sql >> Base de Dados >  >> RDS >> Sqlserver

Por que o SSIS não reconhece o delimitador de linha {LF} de alimentação de linha ao importar o arquivo simples UTF-8?

Causa:


O SSIS não consegue ler o arquivo e exibe o aviso abaixo devido ao delimitador de coluna Ç ("c" com cedilha ) e not devido ao delimitador de linha {LF} (Alimentação de linha ).
[Read flat file [1]] Warning: The end of the data file was reached while 
reading header rows. Make sure the header row delimiter and the number of 
header rows to skip are correct.

Aqui está um pacote SSIS de amostra que mostra como resolver o problema usando Script Component e no final há outro exemplo que simula seu problema.

Resolução:


O pacote de amostra abaixo está escrito em SSIS 2008 R2 . Ele lê um arquivo simples com delimitador de linha {LF} como um valor de coluna única; em seguida, divide os dados usando Script Component para inserir as informações em uma tabela no SQL Server 2008 R2 base de dados.

Use o Notepad++ para criar um arquivo simples simples com poucas linhas. O arquivo de amostra abaixo tem ID do produto e Preço de tabela informações em cada linha separadas por Ç como delimitador de coluna e cada linha termina com {LF} delimitador.



No Notepad++, clique em Encoding e clique em Encoding in UTF-8 para salvar o arquivo simples em UTF-8 codificação.



A amostra usará um SQL Server 2008 R2 banco de dados chamado Sora . Crie uma nova tabela chamada dbo.ProductListPrice usando o script abaixo fornecido. O SSIS inserirá os dados do arquivo simples nessa tabela.
USE Sora;
GO

CREATE TABLE dbo.ProductListPrice
(
        ProductId   nvarchar(30)    NOT NULL
    ,   ListPrice   numeric(12,2)   NOT NULL
);
GO

Crie um pacote SSIS usando o Business Intelligence Development Studio (BIDS) 2008 R2 . Nomeie o pacote como SO_6268205.dtsx . Crie uma fonte de dados chamada Sora.ds para se conectar ao banco de dados Sora em SQL Server 2008 R2 .

Clique com o botão direito do mouse em qualquer lugar dentro do pacote e clique em Variables para visualizar o painel de variáveis. Crie uma nova variável chamada ColumnDelimiter do tipo de dados String no escopo do pacote SO_6268205 e defina a variável com o valor Ç



Clique com o botão direito do mouse em Connection Managers e clique em New Flat File Connection... para criar uma conexão para ler o arquivo simples.



No General página do Editor do Gerenciador de Conexão de Arquivo Simples , execute as seguintes ações:
  • Definir Nome do gerenciador de conexões para ProductListPrice
  • Definir Descrição para Flat file connection manager to read product list price information.
  • Selecione o caminho do arquivo simples. Eu tenho o arquivo no caminho C:\Siva\StackOverflow\Files\6268205\ProductListPrice.txt
  • Selecione {LF} de Delimitador de linha de cabeçalho
  • Verifique Column names in the first data row
  • Clique em Columns página



Nas Columns página do Editor do Gerenciador de Conexão de Arquivo Simples , verifique se o Column delimiter está em branco e desativado. Clique em Advanced página.



No Advanced página do Editor do Gerenciador de Conexão de Arquivo Simples , execute as seguintes ações.
  • Definir o Nome para LineData
  • Verifique se o Delimitador de coluna está definido como {LF}
  • Definir o DataType para Unicode string [DT_WSTR]
  • Defina o OutputColumnWidth para 255
  • Clique em Preview página.



Na Preview página do Editor do Gerenciador de Conexão de Arquivo Simples , verifique se os dados exibidos estão corretos e clique em OK .



Você verá a fonte de dados Sora e o gerenciador de conexões de arquivo simples ProductListPrice nos Connection Managers guia na parte inferior do pacote.



Arraste e solte Data Flow Task para o Fluxo de controle tab do pacote e nomeie-o como File to database - Without Cedilla delimiter



Clique duas vezes na Tarefa de fluxo de dados para alternar a visualização para o Data Flow guia no pacote. Arraste e solte uma Flat File Source no Fluxo de dados aba. Clique duas vezes em Fonte de arquivo simples para abrir o Flat File Source Editor .

No Connection Manager página do Editor de fonte de arquivo simples , selecione o Gerenciador de conexões de arquivo simples ProductListPrice e clique em Colunas página.



Nas Columns página do Editor de fonte de arquivo simples , verifique a coluna LineData e clique em OK .



Arraste e solte um Script Component no Fluxo de dados guia abaixo da Fonte de arquivo simples , selecione Transformation e clique em OK . Conecte a seta verde de Fonte de arquivo simples para Componente de script . Clique duas vezes em Componente de script para abrir o Script Transformation Editor .

Clique em Colunas de entrada no Editor de Transformação de Script e selecione LineData coluna. Clique em Entradas e Saídas página.



Nas Inputs and Outputs página do Editor de Transformação de Script , execute as seguintes ações.
  • Altere o nome das entradas para FlatFileInput
  • Altere o nome das saídas para SplitDataOutput
  • Selecione Colunas de saída e clique em Add Column . Repita isso novamente para adicionar outra coluna.
  • Nomeie a primeira coluna como ProductId
  • Definir o DataType da coluna ProductId para Unicode string [DT_WSTR]
  • Defina o Comprimento para 30



Nas Inputs and Outputs página do Editor de Transformação de Script , execute as seguintes ações.
  • Nomeie a segunda coluna como ListPrice
  • Definir o DataType da coluna ListaPreço para numeric [DT_NUMERIC]
  • Defina a Precisão para 12
  • Definir a Escala para 2
  • Clique em Script página para modificar o script



No Script página do Editor de Transformação de Script , execute as seguintes ações.
  • Clique no botão de reticências em ReadOnlyVariables e selecione a variável User::ColumnDelimiter
  • Clique em Edit Script...



Cole o C# abaixo no Editor de Scripts. O script executa as seguintes tarefas.
  • Usando o valor do delimitador de coluna Ç definido na variável User::ColumnDelimiter , o método FlatFileInput_ProcessInputRow divide o valor de entrada e o atribui às duas colunas de saída definidas na transformação do Script Component.

Código do componente de script em C#

using System;
using System.Data;
using Microsoft.SqlServer.Dts.Pipeline.Wrapper;
using Microsoft.SqlServer.Dts.Runtime.Wrapper;

[Microsoft.SqlServer.Dts.Pipeline.SSISScriptComponentEntryPointAttribute]
public class ScriptMain : UserComponent
{
    public override void PreExecute()
    {
        base.PreExecute();
    }

    public override void PostExecute()
    {
        base.PostExecute();
    }

    public override void FlatFileInput_ProcessInputRow(FlatFileInputBuffer Row)
    {
        const int COL_PRODUCT = 0;
        const int COL_PRICE = 1;

        char delimiter = Convert.ToChar(this.Variables.ColumnDelimiter);
        string[] lineData = Row.LineData.ToString().Split(delimiter);

        Row.ProductId = String.IsNullOrEmpty(lineData[COL_PRODUCT]) 
                            ? String.Empty 
                            : lineData[COL_PRODUCT];

        Row.ListPrice = String.IsNullOrEmpty(lineData[COL_PRICE]) 
                            ? 0 
                            : Convert.ToDecimal(lineData[COL_PRICE]);
    }
}



Arraste e solte OLE DB Destination no Fluxo de dados aba. Conecte a seta verde do Componente de script para Destino OLE DB . Clique duas vezes em Destino OLE DB para abrir o OLE DB Destination Editor .

No Connection Manager página do Editor de Destino OLE DB , execute as seguintes ações.
  • Selecione Sora do Gerenciador de conexões OLE DB
  • Selecione Table or view - fast load do Modo de acesso a dados
  • Selecione [dbo].[ProductListPrice] de Nome da tabela ou visualização
  • Clique em Mapeamentos página



Clique em Mappings página no Editor de destino OLE DB mapearia automaticamente as colunas se os nomes das colunas de entrada e saída fossem os mesmos. Clique em OK .



Fluxo de dados tab deve ficar assim depois de configurar todos os componentes.



Execute a consulta select * from dbo.ProductListPrice no SQL Server Management Studio (SSMS) para encontrar o número de linhas na tabela. Ele deve estar vazio antes de executar o pacote.



Execute o pacote. Você notará que o pacote processou com sucesso 9 linhas. O arquivo simples contém 10 linhas, mas a primeira linha é o cabeçalho com os nomes das colunas.



Execute a consulta select * from dbo.ProductListPrice no SQL Server Management Studio (SSMS) para encontrar os 9 linhas inseridas com sucesso na tabela. Os dados devem corresponder aos dados do arquivo simples.



O exemplo acima ilustrou como dividir manualmente os dados usando o Script Component porque o Gerenciador de conexões de arquivo simples encontra erro ao configurar o delimitador de coluna Ç

Simulação de problemas:


Este exemplo mostra um Gerenciador de conexões de arquivo simples separado configurado com delimitador de coluna Ç , que é executado, mas encontra um aviso e não processa nenhuma linha.

Clique com o botão direito do mouse em Connection Managers e clique em New Flat File Connection... para criar uma conexão para ler o arquivo simples. No General página do Editor do Gerenciador de Conexão de Arquivo Simples , execute as seguintes ações:
  • Definir Nome do gerenciador de conexões para ProductListPrice_Cedilla
  • Defina Descrição como Flat file connection manager with Cedilla column delimiter.
  • Tenho o arquivo no caminho C:\Siva\StackOverflow\Files\6268205\ProductListPrice.txt Selecione o caminho do arquivo simples.
  • Selecione {LF} de Delimitador de linha de cabeçalho
  • Verifique Column names in the first data row
  • Clique em Columns página



Nas Columns página do Editor do Gerenciador de Conexão de Arquivo Simples , execute as seguintes ações:
  • Definir Delimitador de linha para {LF}
  • O campo delimitador de coluna pode estar desabilitado. Clique em Reset Columns
  • Definir delimitador de coluna para Ç
  • Clique em Advanced página



No Advanced página do Editor do Gerenciador de Conexão de Arquivo Simples , execute as seguintes ações:
  • Definir o Nome para ProductId
  • Defina o ColumnDelimiter para Ç
  • Definir o DataType para Unicode string [DT_WSTR]
  • Defina o Comprimento para 30
  • Clique na coluna ListPrice



No Advanced página do Editor do Gerenciador de Conexão de Arquivo Simples , execute as seguintes ações:
  • Definir o Nome para ListPrice
  • Defina o ColumnDelimiter para {LF}
  • Definir o DataType para numeric [DT_NUMERIC]
  • Defina o DataPrecision para 12
  • Definir o DataScale para 2
  • Clique em OK



Arraste e solte uma Data Flow task para o Fluxo de controle tab e nomeie-o como File to database - With Cedilla delimiter . Desative a primeira tarefa de fluxo de dados.



Configure a segunda tarefa de fluxo de dados com Flat File Source e OLE DB Destination



Clique duas vezes na Fonte de Arquivo Simples para abrir o Flat File Source Editor . No Connection Manager página do Editor de fonte de arquivo simples , selecione o Gerenciador de conexões de arquivo simples ProductListPrice_Cedilla e clique em Colunas página para configurar as colunas. Clique em OK .



Execute o pacote. Todos os componentes exibirão a cor verde para indicar que o processo foi bem-sucedido, mas nenhuma linha será processada. Você pode ver que não há indicação de números de linhas entre a Flat File Source e OLE DB Destination



Clique em Progress guia e você notará a seguinte mensagem de aviso.
[Read flat file [1]] Warning: The end of the data file was reached while 
reading header rows. Make sure the header row delimiter and the number of 
header rows to skip are correct.