Olá pessoal…
Hoje vou mostrar um exemplo simples de como pegar o conteúdo de um campo MEMO do SQL Server via AdvPL (tanto o campo IMAGE, quanto pegando via SYP).
Existe dois tipos de campo MEMO no Protheus, um que usa o tipo IMAGE, sendo necessário converter para VARCHAR, e um que grava tudo na tabela SYP, quebrando linha pela expressão “\13\10”. Abaixo mostro um exemplo de cada.
Pelo campo tipo IMAGE
Pelo campo Image, basta converter como VARBINARY para VARCHAR, com o tamanho máximo de 8000 bytes. No exemplo abaixo, eu pego o campo B1_COD, o B1_DESC e converto o B1_X_OBS usando esse comando.
SELECT B1_COD, B1_DESC, ISNULL(CAST(CAST(B1_X_OBS AS VARBINARY(8000)) AS VARCHAR(8000)),'') AS OBS FROM SB1010 SB1
Dessa forma, ele pega o conteúdo do B1_X_OBS, e converte para ser visível e possível a manipulação.
Update Março de 2024:
Pessoal, o grande Jonathan Silva ( LinkedIn ), passou um exemplo de como fazer a query, mas no banco de dados Oracle, segue abaixo:
SELECT B1_COD, B1_DESC, REPLACE(REPLACE(utl_raw.cast_to_varchar2(DBMS_LOB.SUBSTR(SB1.B1_X_OBS ,1024,1)),chr(13),''),chr(10),'') AS OBS --1024 é o número de caracteres que foi usado no exemplo FROM SB1010 SB1
Pela tabela SYP ou RDY (formas antigas)
A tabela SYP (ou RDY), era a forma antiga do Protheus controlar os campos MEMO (através da função MSMM), e nesse tipo, ele gerava vários registros com textos, por exemplo, a cada x caracteres gera uma nova linha, e para buscar isso via SQL Server, podemos fazer uma subquery, buscando pela chave da tabela, e montando a expressão em uma única linha com FOR XML PATH.
SELECT UC_DTENCER AS DT_ENCER, UC_DATA AS DT_2, ISNULL( CONVERT(VARCHAR(400), ( SELECT RTRIM(SYP.YP_TEXTO) FROM SYP010 SYP WHERE SYP.YP_CHAVE = SUC.UC_CODOBS AND SYP.YP_CAMPO = 'UC_CODOBS' AND SYP.D_E_L_E_T_ = ' ' ORDER BY YP_SEQ FOR XML PATH ('') )), '') AS ATIVIDADE FROM SUC010 SUC
No exemplo acima, delimitamos que queremos até 400 caracteres, e fazemos uma subquery buscando os dados da SYP.
Obs.: Como lembrado pelo Leandro Michelsen nos comentários, pode ser que em algumas situações a quebra de linha esteja gravada como \13\10 tendo de ser tratado, como por exemplo com o comando replace.
Bom pessoal, por hoje é só.
Abraços e até a próxima.
O campo YP_TEXTO possui, em alguns casos, a string ‘\13\10’ indicando quebra de linha. Para isso ajustei a query adicionando a função REPLACE:
REPLACE(ISNULL (CONVERT(VARCHAR(4000),(SELECT RTRIM(SYP.YP_TEXTO) FROM SYP010 SYP WHERE SYP.YP_CHAVE = SB1.B1_DESC_GI AND SYP.YP_CAMPO = ‘B1_DESC_GI’ AND SYP.D_E_L_E_T_ = ‘ ‘ ORDER BY YP_SEQ FOR XML PATH (”) )), ‘ ‘),’\13\10’,”) AS DESCRI
Opa, muito obrigado pela contribuição Leandro.
Um grande abraço.