Como ler campos virtuais do tipo memo no SQL
Os campos “memos” no protheus em sua maioria é do tipo virtual, pois este utiliza uma tabela “Descrições dos campos memo” (SYP) auxiliar para armazenar o conteúdo destes campos.
Como exemplo, temos a tabela “Descrição Genérica de Produtos” (SB1).
Para entender melhor, o campo B1_VM_P (Descrição em Português) é um campo virtual do tipo memo de tamanho 36, seu inicializador padrão utiliza a função E_MSMM para ler o conteúdo do campo B1_DESC_P (Código da descrição em português), campo este que contém o código chave que servirá de referência para localizar o descrição na tabela “Descrições dos campos memo” (SYP).
Neste exemplo, para cada linha com 36 caracteres será uma nova linha na tabela SYP.
Consultando no banco de dados, o registro fica conforme a imagem abaixo:
Agora vamos ao que interessa, preciso montar uma consulta SQL que me mostre os registros da tabela SB1 e que me traga o conteúdo do campo memo do campo B1_DESC_P.
É uma consulta simples, fazer um SELECT na tabela SYP porém informando o código chave da tabela SB1, mas preciso trazer todas as linhas da SYP numa única linha e apresentá-la junto a consulta principal.
Uma forma fácil de fazer isso é colocando uma sub-consulta SQL usando o comando “CASE” do SQL.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
/*consulta simples a tabela SYP sem uso do CASE*/ SELECT * FROM SYP010 WHERE YP_CHAVE='000007' AND D_E_L_E_T_='' /*consultar a tabela SYP com uso do CASE*/ --Consultando a primeira linha SELECT CASE (SELECT COUNT(YP_TEXTO) FROM SYP010 WHERE YP_CHAVE='000007' AND YP_SEQ='001' AND D_E_L_E_T_='') WHEN 0 THEN '' ELSE UPPER((SELECT YP_TEXTO FROM SYP010 WHERE YP_CHAVE='000007' AND YP_SEQ='001' AND D_E_L_E_T_='')) END --Consultando a segunda linha SELECT CASE (SELECT COUNT(YP_TEXTO) FROM SYP010 WHERE YP_CHAVE='000007' AND YP_SEQ='002' AND D_E_L_E_T_='') WHEN 0 THEN '' ELSE UPPER((SELECT YP_TEXTO FROM SYP010 WHERE YP_CHAVE='000007' AND YP_SEQ='002' AND D_E_L_E_T_='')) END --Consultando a terceira linha SELECT CASE (SELECT COUNT(YP_TEXTO) FROM SYP010 WHERE YP_CHAVE='000007' AND YP_SEQ='003' AND D_E_L_E_T_='') WHEN 0 THEN '' ELSE UPPER((SELECT YP_TEXTO FROM SYP010 WHERE YP_CHAVE='000007' AND YP_SEQ='003' AND D_E_L_E_T_='')) END --Agora concatenando SELECT ( --Consultando a primeira linha SELECT RTRIM(CASE (SELECT COUNT(YP_TEXTO) FROM SYP010 WHERE YP_CHAVE='000007' AND YP_SEQ='001' AND D_E_L_E_T_='') WHEN 0 THEN '' ELSE UPPER((SELECT YP_TEXTO FROM SYP010 WHERE YP_CHAVE='000007' AND YP_SEQ='001' AND D_E_L_E_T_='')) END) + --Consultando a segunda linha RTRIM(CASE (SELECT COUNT(YP_TEXTO) FROM SYP010 WHERE YP_CHAVE='000007' AND YP_SEQ='002' AND D_E_L_E_T_='') WHEN 0 THEN '' ELSE UPPER((SELECT YP_TEXTO FROM SYP010 WHERE YP_CHAVE='000007' AND YP_SEQ='002' AND D_E_L_E_T_='')) END) + --Consultando a terceira linha RTRIM(CASE (SELECT COUNT(YP_TEXTO) FROM SYP010 WHERE YP_CHAVE='000007' AND YP_SEQ='003' AND D_E_L_E_T_='') WHEN 0 THEN '' ELSE UPPER((SELECT YP_TEXTO FROM SYP010 WHERE YP_CHAVE='000007' AND YP_SEQ='003' AND D_E_L_E_T_='')) END) ) AS MEMO |
Mas como disse acima, a cada 36 caracteres é uma linha na tabela SYP, esta tabela possui um campo chamado YP_SEQ, ele contém a sequência de linhas. O campo memo pode ter várias e varias linhas, neste exemplo quero pegar apenas as 3 primeiras linhas.
Consulta completa:
1 2 3 4 5 6 7 8 9 10 11 |
SELECT B1_COD,B1_DESC,B1_UM, ( SELECT (CASE (SELECT COUNT(YP_TEXTO) FROM SYP010 WHERE YP_CHAVE=B1_DESC_P AND YP_SEQ='001' AND D_E_L_E_T_='') WHEN 0 THEN '' ELSE UPPER((SELECT YP_TEXTO FROM SYP010 WHERE YP_CHAVE=B1_DESC_P AND YP_SEQ='001' AND D_E_L_E_T_='')) END) + (CASE (SELECT COUNT(YP_TEXTO) FROM SYP010 WHERE YP_CHAVE=B1_DESC_P AND YP_SEQ='002' AND D_E_L_E_T_='') WHEN 0 THEN '' ELSE UPPER((SELECT YP_TEXTO FROM SYP010 WHERE YP_CHAVE=B1_DESC_P AND YP_SEQ='002' AND D_E_L_E_T_='')) END) + (CASE (SELECT COUNT(YP_TEXTO) FROM SYP010 WHERE YP_CHAVE=B1_DESC_P AND YP_SEQ='003' AND D_E_L_E_T_='') WHEN 0 THEN '' ELSE UPPER((SELECT YP_TEXTO FROM SYP010 WHERE YP_CHAVE=B1_DESC_P AND YP_SEQ='003' AND D_E_L_E_T_='')) END) ) AS DESCR_PORT FROM SB1010 WHERE D_E_L_E_T_='' ORDER BY B1_COD |
A consulta retornar todos os registros incluindo o conteúdo do campo memo, concatenando as 3 linhas contidas na tabela SYP.
Agora fica mais fácil apresentar campos memo dentro de um relatório no Protheus, pois o campo passa a ser do tipo caracter.
Esperamos que tenha ajudado.
abraços e até a próxima.
Deixe uma resposta