Eu tenho um arquivo de dados de texto simples contendo registros cujos campos são separados pelo caractere não imprimível "File Separator" (0x1c) . Estou tentando usar o utilitário bcp do SQL Server para carregar esses dados no meu banco de dados. No entanto, ao usar o valor codificado em hexadecimal do Separador de Arquivos como TERMINATOR, recebo um erro de sintaxe.
ja tentei usar
- o valor codificado hexadecimal:
"0x1c"
- o valor codificado em XML como hexadecimal:
""
- o valor codificado em XML como decimal:
""
Nada disso funciona, mas ao usar a mesma codificação para um caractere imprimível, como tab
, isso funciona: 	
, 	
( 0x9
não funciona. Não é surpresa, pois este é um arquivo XML.)
A conclusão parece ser que os caracteres não imprimíveis não são suportados. É este o caso? Isso seria irônico, já que os caracteres separadores não imprimíveis são criados exatamente para esse fim...
Abaixo você pode encontrar todo o código para reproduzir este problema:
Arquivo de formato XML: test.xml
<?xml version="1.0"?>
<BCPFORMAT xmlns="http://schemas.microsoft.com/sqlserver/2004/bulkload/format" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<RECORD>
<FIELD ID="1" xsi:type="CharTerm" TERMINATOR="" MAX_LENGTH="10" COLLATION="Latin1_General_CS_AS_WS"/>
<FIELD ID="2" xsi:type="CharTerm" TERMINATOR="\r\n" MAX_LENGTH="41"/>
</RECORD>
<ROW>
<COLUMN SOURCE="1" NAME="COL1" xsi:type="SQLVARYCHAR"/>
<COLUMN SOURCE="2" NAME="COL2" xsi:type="SQLNUMERIC" PRECISION="4" SCALE="0"/>
</ROW>
</BCPFORMAT>
Arquivo de dados: test.txt
Esta é apenas uma linha, como um caso de teste. O StackExchange não mostra o separador na linha abaixo, mas quando você clica em "Editar" para esta postagem, o separador é incluído e você deve poder copiar e colar isso.
1111111112008
Linha de comando
bcp TEST_DB.dbo.UL_TEST in "test.txt" -T -f "test.xml"
Parece , da documentação sobre BCP - Especificar Terminadores de Campo e Linha (SQL Server) , que os caracteres não imprimíveis não são suportados:
Como opção, você pode usar
POWERSHELL
para ler o arquivo de origem e pesquisar\substituir os0x1C
caracteres por algum outro caractere como um tilda (~) e enviar para um arquivo diferente. Em seguida, use esse caractere como seu terminador.Como @ScottHodgin apontou que caracteres não imprimíveis não são suportados, substituí-los no arquivo de origem é a única alternativa.
Abaixo, você pode encontrar um exemplo de script do PowerShell que pode fazer essa substituição em um arquivo codificado em UTF8 (com ou sem cabeçalho BOM não importa) e grava um arquivo de saída codificado em UTF8 sem um cabeçalho BOM.
Além disso, ele usa AppendAllLines para transformar isso em uma operação de streaming. Dessa forma, também funciona para arquivos grandes, pois eles não precisam ser totalmente carregados na memória antes de fazer as substituições. -ReadCount 1000 acelera o processo drasticamente.
Certifique-se de salvar o script acima em um arquivo codificado com UTF8 com cabeçalho BOM, caso contrário, o PowerShell não processa os caracteres como UTF-8.