none
Imagem em Doc xml RRS feed

  • Pergunta

  • Bom dia,

    Tenho a seguinte situação. Tenho uma aplicação que envia para uma proc um xml com um binário. Ex:

    <Retorno>

    <PDF>233232326520322</PDF>

    </Retorno>

    Esse dado já está no formato hexadecimal, apenas faltando o 0x.

    A questão é mesmo utilizando o 0x (quando feito tratativa para incluí-lo), ao tentar inserir esse dado em um campo do tipo image, ele o interpreta como uma variável do tipo texto e o transforma em binário

    gravado po exempo de 0x2df1d2f5f4... para 0x30154521... . 

    Esses dados são recebido pela proc da seguinte aneira:

    SELECT

    convert(image,(CONVERT(varchar(max),Colx.query('data(PDF)'))))n
    FROM @XML.nodes('Retorno') AS Tabx(Colx)  .

    sendo que é impossível utilizar nvarchar com image , ou image direto.

    Como conseguiria gravar esse dado 0x2df1d2f5f4 no compa, fazendo-o entender de que ele já está como hexadecimal.

    quinta-feira, 16 de julho de 2015 18:28

Respostas

Todas as Respostas

  • Deleted
    quinta-feira, 16 de julho de 2015 19:53
  • Bom dia,

    Obrigado pelo retorno. O meu problema é que não quero uma conversão, pois assim ele transforma o dígito string em hexadecimal (ex: 255 em FF). 

    O que necessito é que ele insira em um campo do tipo image exatamente como estou enviando. Digamos, estou enviando a string 0x2550444, ele grave na base 0x2550444 e não 0xFFF3.

    Mas obrigado pela ajuda.

    Att. Leonardo de Paula.

    terça-feira, 21 de julho de 2015 12:23
  • Para esclarecer, se você passar o valor 0x2550444 o SQL armazena 4 bytes(0x44, 0x04, 0x55 e 0x02).
    Se você passar como string '0x2550444' ele armazena um byte(código ASCII) para cada caractere.

    Crie a tabela, insira os valores e pesquise com SELECT.

    CREATE TABLE TB_TESTE (IMG IMAGE)
    
    INSERT INTO TB_TESTE VALUES (CHAR(35)) --Funciona
    INSERT INTO TB_TESTE VALUES (0x400) --Funciona
    INSERT INTO TB_TESTE VALUES ('0x5821') -- Funciona
    INSERT INTO TB_TESTE VALUES (1024) --Erro: Operand type clash: int is incompatible with image

    Para fazer o que você deseja precisa rolar CONVERT, apesar deste tipo de dados não ser o mais indicado.


    terça-feira, 21 de julho de 2015 13:35
  • Deleted
    terça-feira, 21 de julho de 2015 23:23
  • Leonardo, sempre que um valor for armazenado em uma coluna do tipo IMAGE,

    • ou esse valor deve estar no tipo de dados IMAGE (usando previamente função Cast ou Convert)
    • ou ocorrerá uma conversão implícita criada pelo SQL Server
    • ou ocorrerá erro de conversão.

      

    Na documentação da função Convert, no item "Conversões implícitas" consta que ocorrerá conversão implícita quando a expressão a ser armazenada for do tipo binary, varbinary, char, varchar e timestamp, sendo os demais casos não aceitos.

    Então, para evitar a conversão implícita, o melhor é previamente converter para IMAGE.

    Na mensagem inicial deste tópico você cita que recebe xml com binário. Mas na realidade o que está recebendo é uma sequência de caracteres que, pelo compreendi, é uma representação hexadecimal de algum binário ("Esse dado já está no formato hexadecimal").

    Se executar o código abaixo perceberá que o string xml recebido
         <PDF>23323232652032</PDF>

    é armazenado corretamente na coluna BinarioDoc da tabela Documentos.

    -- código 3 v2
    use TempDB;
    go
    
    CREATE TABLE Documentos (ID int, BinarioDoc image);
    go
    
    declare @PDFc varchar(max), @PDFb varbinary(max);
    set @PDFc= '23323232652032';
    set @PDFb= 0x23323232652032;

    INSERT into Documentos values
       (1, Cast(Convert(varbinary(max), @PDFc, 2) as image)),
       (2, Cast(@PDFb as image)),
       (3, @PDFb);
    SELECT * from Documentos;
     

    A variável @PDFc é a que simula o retorno de Colx.query('data(PDF)'), após conversão de XML para caractere.

    Acrescentei a variável @PDFb, onde o valor hexadecimal é assinalado diretamente. Observe que o resultado é sempre o mesmo.

    Se analisar o plano de execução do código 3, perceberá que a terceira inclusão
            (3, @PDFb);
    aciona a função CONVERT_IMPLICIT.

     

    Com relação ao código 2, eis ele atualizado:

    -- código 2 v3
    SELECT Cast(Convert(varbinary(max), Convert(varchar(max), Colx.query('data(PDF)')), 2) as image) as n
      from @XML.nodes('Retorno') as Tabx(Colx);
         

    O método query retorna conteúdo no tipo XML. Então é necessário primeiro convertê-lo para string para somente após convertê-lo para binário. E após para Image. São três conversões...

    Eis a prova do funcionamento do código 2:

    -- código 4
    use TempDB;
    
    declare @XML XML;
    set @XML= '<Retorno> <PDF>23323232652032</PDF> </Retorno>';  
    INSERT into Documentos
      SELECT 4, Cast(Convert(varbinary(max), Convert(varchar(max), Colx.query('data(PDF)')), 2) as image) as n
        from @XML.nodes('Retorno') as Tabx(Colx);
    
    SELECT *
      from Documentos;




        José Diz     Belo Horizonte, MG - Brasil
    (Se encontrou a solução nesta resposta, ou se o conteúdo foi útil, lembre-se de marcá-la)



    José,

    Perfeito! Não há como armazenar e obter os dados de um arquivo, seja imagem ou outros (word, pdf, ...) sem um CONVERT.

    Leonardo,

    Recomendo fortemente a opção indicada pelo José.


    Se ajudou na sua solução, não esqueça de marcar como resposta !


    Abraços,

    Durval Ramos
    Microsoft Partner | MTA | MCSA - SQL Server 2012 | MCSE - Data Platform
    ----------------------------------
    Se foi resolvido clique "Marcar como resposta" e se foi útil "Votar como Útil"

    quarta-feira, 22 de julho de 2015 22:07
    Moderador