Estou usando o seguinte comando para gravar a saída de um procedimento armazenado em um arquivo para processamento adicional:
DECLARE @shellCommand VARCHAR(2000)
SET @shellCommand = 'SQLCMD -S ' + @@SERVERNAME + ' -d ' + @dbName + ' -U ' + @UserName + ' -P ' + @Password + ' -Q "' + @sqlCommand + '" -s "," -h -1 -k 1 -W -o "' + @outputfileName + '"'
@sqlCommand
está definido corretamente, como "EXEC StoredProcedureName parameterValue" e quando executado de forma independente aparentemente produz os dados corretos.
O problema que estou tendo é que um dos campos contém texto com mais de 256 caracteres e está sendo truncado quando alimentado por meio do comando SQLCMD.
Ao ler a documentação , vejo que a largura padrão da coluna é de 256 caracteres. Então, estou olhando para usar a opção -y
ou -Y
para permitir que mais de 256 caracteres sejam gerados. No entanto, essas opções não são compatíveis com a -W
opção que eu estava usando para remover espaços à direita da saída. Comecei usando -y 0
(apesar do aviso de desempenho - assim que a saída funcionar, posso observar o desempenho). No entanto, isso produz alguns resultados estranhos.
O arquivo consiste em uma linha de cabeçalho seguida pelas linhas de dados e deve se parecer com isto:
First,ABC,Number,String,ReallyLongString,...
A,0123,14.99,"Short string","Longish string",...
B,0456,23.99,"Normal string","Really, really long string that's causing problems",...
Com a -W
opção, o formato do arquivo está correto, mas a string realmente longa é truncada. A razão pela qual descobrimos foi porque o final "
estava faltando e o arquivo não estava sendo lido corretamente.
Com -y 0
a string realmente longa está obtendo saída, mas um grande número de espaços está sendo adicionado a colunas aparentemente aleatórias. Estamos recebendo algo assim:
First,ABC ,Number [...] ,String,ReallyLongString,...
A ,0123,14.99 [...] ,"Short string","Longish string",...
B ,0456,23.99 [...] ,"Normal string","Really, really long string that's causing problems",...
(Existem muitos, muitos mais espaços entre "Número" e a próxima coluna representada pelo "[...]", estou apenas mostrando alguns).
Existem mais valores numéricos que precisam ser formatados de maneira semelhante e parece que são esses que estão causando os espaços extras após o valor e antes da próxima vírgula. Podemos conviver com alguns espaços extras, mas não tantos, pois o arquivo resultante é muito grande para ser lido pelo programa de destino.
Os dados são gerados por um procedimento armazenado que se parece com isso:
SELECT
'First' AS First,
'ABC' AS ABC,
'Number' AS Number,
'String' AS String,
'ReallyLongString' AS ReallyLongString,
...
UNION ALL
SELECT
'A' as First,
Column1 as ABC,
REPLACE(FORMAT(Column2, 'N2', 'en-GB'), ',', '') as Number, -- to get the format correct
'"' + Column3 + '"' as String,
'"' + Column4 + '"' as ReallyLongString,
....
FROM Table
WHERE <condition>
Estou pensando que o problema é a saída do procedimento armazenado. Eu só adicionei a -W
opção ao SQLCMD por causa dos espaços extras à direita sendo gerados, mas olhando para o procedimento armazenado, não consigo descobrir de onde eles estão vindo. Alterei a formatação do número para incluir RTRIM
:
RTRIM(REPLACE(FORMAT(Column2, 'N2', 'en-GB'), ',', ''))
mas isso parecia não fazer diferença.
Existe algo que eu possa fazer com o procedimento armazenado ou existe uma combinação de opções para SQLCMD que produzirá a saída desejada? Ou vou ter que encontrar alguma outra forma de produzir esse arquivo?
Ao experimentar as várias sugestões nos comentários, encontrei uma solução.
troquei:
com:
e todo o texto foi produzido.
No entanto, usando uma variável:
não.
O que funcionou foi declarar a variável com um comprimento específico:
Portanto, como o texto neste caso nunca terá mais de 2.000 caracteres (o dispositivo que está lendo o arquivo não pode lidar com texto tão longo), converto todo o texto em strings de 2.000 caracteres:
Este é o como. Ainda não sei bem o porquê.
Estranho... usar
-y 0
realmente funciona perfeitamente para mim. Sem preenchimento de espaço em branco ou quaisquer outros problemas de formatação. Na verdade, funciona melhor do que-W
, mesmo que a documentação não explique o porquê e ainda recomende o uso de-W
:Embora não esteja documentado, parece que
-y 0
realmente faz o que-W
anuncia e muito mais (comprimento de string ilimitado e até mesmo remove os cabeçalhos, portanto, não há necessidade de-h-1
). A única outra opção que tive que usar foi-s ","
especificar um separador de coluna diferente.Estou usando a versão
13.1.0007.0
no Linux, então talvez o problema do OP seja algo que foi corrigido em versões superiores.O único problema que encontrei foi um caractere não imprimível (o que parece uma caixa) sendo adicionado no final de strings muito longas (mais de 100K caracteres), mas quando as strings são citadas (
'"' + field + '"'
), o caractere desaparece. ¯\_(ツ)_/¯Nas opções do SSMS, altere Resultados da consulta > Resultados para texto > Número máximo de caracteres exibidos em cada coluna: