Árvore de páginas

Versões comparadas

Chave

  • Esta linha foi adicionada.
  • Esta linha foi removida.
  • A formatação mudou.

...

Um programa é constituído por funções e declarações. A primeira função a ser executada é a função "MAIN", e, tem de existir em todos os programas.

 

Fonte olamundo.4gl

MAIN
   ...instruções...
END MAIN

Exemplo de programa

...

Como linguagem de gerenciamento de base de dados, o 4GL reconhece as estruturas representáveis na base de dados, e, algumas de maior complexidade. Os tipos de dados complexos, são declarados por composição de tipos elementares. Em 4GL os tipos de dados elementares existentes utilizados no produto LOGIX são:

 SMALLINT
Números inteiros pequenos, uma variável deste tipo pode receber números inteiros entre –32767 e 37767. 

...

Uma variável do tipo decimal não pode exceder 32 dígitos significativos.

CHAR(n)
Alfanumérico de comprimento “n”. Uma variável do tipo CHAR pode ter o tamanho que varia de 1 a 32767.

DATE
Tipo equivalente a uma data, é configurável através da variável de ambiente DBDATE. Internamente, este tipo é armazenado como inteiro, no formato juliano (nº de dias desde 31 de dezembro de 1899). O formato padrão do DBDATE é “mdy4/” ou seja, “mm/dd/yyyy”, onde mm é o mês (1 a 12), dd (1 a 31) é o dia e yyyy o ano (0001 a 9999). O padrão utilizado na Logocenter é “dmy4/”, ou seja, “dd/mm/yyyy”.

...

Uma variável do tipo ARRAY é uma variável estática, ou seja, a memória consumida será sempre conforme o tipo e o número de elementos, podendo ser bi-dimensional se houver necessidade.

RECORD
Representa uma variável composta por diferentes variáveis de qualquer tipo, incluindo os tipos simples (DATE, CHAR, SMALLINT, INTEGER, etc) e os tipos compostos (ARRAY e RECORD).  Assemelha-se ao conceito de variável do tipo STRUCT da linguagem C. 

...

A declaração de variáveis é sempre efetuada depois da palavra chave "DEFINE". Uma variável declara-se da seguinte forma:
   

 

DEFINE nome_da_variavel TIPO
 OU
DEFINE nome_da_variavel LIKE tabela.coluna 

 

No segundo caso cria-se uma nova variável cuja estrutura condiz com a estrutura de uma coluna de uma tabela do banco de dados. Sempre que uma variável for declarada usando a instrução LIKE, deve existir no início do módulo (fonte .4gl) uma instrução DATABASE que indica o banco de dados a ser usado para obter informações de definição das colunas utilizadas na declaração de variáveis.

Um caracter ou uma faixa de caracteres (substring) pertencentes a uma variável do tipo CHAR pode ser acessado utilizando o operador “[]” (colchetes), assim:

 

 l_texto[1]
 OU
l_texto[2,5] 

 

...

Se a variável for um DATETIME deve-se declarar da seguinte forma:

 

nome_do_datetime DATETIME qualificador_inicial TO qualidificador_final

 

Para uma variável DATETIME que tem o formato que vai do ano até 5 dígitos de fração de segundo, deve-se definir assim:

 

l_datahora DATETIME YEAR TO FRACTION(5)

 

Se a variável for um RECORD deve-se apenas declarar da seguinte forma:

 

nome_do_record RECORD
        lista_de_variaveis
END RECORD

 OU

nome_do_record RECORD LIKE tabela.*

 

No segundo caso é criada uma estrutura com elementos idênticos a todas as colunas de uma tabela do banco de dados corrente.

...

Se a variável for um array deve ser declarada da seguinte forma:

 

 nome_da_variavel ARRAY[m,n,...] OF tipo

 

Os elementos das variáveis tipo ARRAY podem ser acessadas através do operador [] (colchetes) e dá indicação do número do elemento a que se quer ter acesso, assim:

...

2.3.1       Variáveis locais

 

DEFINE nome_da_variável tipo [, ...]

 

...

 

 varlocal.4gl

MAIN
   DEFINE l_inteiro INTEGER   
   LET l_inteiro = 1
   CALL mostra_local()
   CALL mostra_local_agora(l_inteiro)
END MAIN

FUNCTION mostra_local()
  DEFINE l_inteiro INTEGER
  DISPLAY “INTEIRO: “, l_inteiro
  SLEEP 2
END FUNCTION

FUNCTION mostra_local_agora(l_inteiro)
DEFINE l_inteiro INTEGER
DISPLAY “INTEIRO AGORA: “,l_inteiro
  SLEEP 2
END FUNCTION

RESULTADO:
INTEIRO:           0
INTEIRO AGORA: 1

 

...

2.3.2       Variáveis globais

 

GLOBALS "fonte.4gl"

 OU 

GLOBALS
   {instrução DEFINE}
END GLOBALS}

 

Definição genérica de uma declaração global

...

2.3.3       Variáveis modulares

 

DEFINE nome_da_variável tipo [, ...]

 

 

As variáveis modulares tem que ser declaradas no inicio do fonte, fora do escopo de definição de variáveis globais (GLOBALS..END GLOBALS) e fora do escopo de qualquer função (MAIN, FUNCTION, REPORT). Variáveis modulares somente são reconhecidas dentro do escopo do fonte (módulo) em que foram declaradas.

 

varmod1.4gl

DEFINE m_inteiro INTEGER

MAIN
   LET m_inteiro = 1
   DISPLAY “inteiro VARMOD1: “,m_inteiro
   SLEEP 2
   CALL mostra_varmod2()
   DISPLAY "VARMOD1 após VARMOD2: ",g_inteiro
   SLEEP 2
END MAIN

varmod2.4gl

DEFINE m_inteiro INTEGER
FUNCTION mostra_varmod2()
DISPLAY “inteiro VARMOD2: “,m_inteiro
SLEEP 2
LET m_inteiro = 3

 END FUNCTION

RESULTADO
inteiro VARMOD1:           1
inteiro VARMOD2:           0 
VARMOD1 após VARMOD2:           1

Exemplo com variáveis modulares

 

...

  

Se declarar duas variáveis modulares com o mesmo nome em dois fontes (módulos) distintos, cada variável só vai ser reconhecida no fonte onde foi declarado. Efetivamente as variáveis com o mesmo nome localizadas em fontes diferentes são variáveis diferentes.

...

No 4GL para atribuir a uma variável um valor constante, expressão ou conteúdo de outra variável, utiliza-se o seguinte formato:

 

LET variável = {expressão | variável | constante}

Definição genérica da atribuição

No 4GL pode-se inicializar uma variável de qualquer tipo básico. As variáveis compostas só podem ser inicializadas através dos seus elementos constituintes.

 

afecta.4gl

DATABASE livros
MAIN
   DEFINE x INTEGER,
          y CHAR(20),
          z DECIMAL(5,2),
          lr_livros RECORD LIKE livros.*,
          lr_livros2 RECORD LIKE livros.*
   LET x = 69
   LET y = "Uma string"
   LET z = 120.596
   DISPLAY "X tem ", x,", Y tem ", y,"e Z = ",z

   SELECT *
     INTO lr_livros.*
     FROM livros
   WHERE numero = x
   LET lr_livros2.* = lr_livros.*
   DISPLAY lr_livros2.numero, lr_livros.nome
END MAIN

RESULTADO:
X tem 69, Y tem Uma string e Z = 120.60
69 nome do livro 69

Inicializações de variáveis

...

 

 compara.4gl

MAIN   DEFINE y CHAR(20)
   LET y = "Uma string"
   IF y > "UMA STRING" THEN
      DISPLAY "Uma string maior que UMA STRING"
   END IF

   IF y < "uma string" THEN
      DISPLAY "Uma string menor que UMA STRING"
   END IF

   IF y = "Uma string" THEN
      DISPLAY "Uma string igual a UMA STRING"
   END IF
END MAIN

RESULTADO:
 Uma string maior que UMA STRING
 Uma string menor que UMA STRING
 Uma string igual a UMA STRING 

Vários exemplos de comparações

...

Uma das formas de o fazer é inicializando a variável com o valor pretendido, na área do programa em que se pretende fazer. Outra forma é utilizando a instrução INITIALIZE.

 

INITIALIZE lista_de_variáveis TO NULL

Definição genérica da instrução INITIALIZE

...

 

concat.4gl

MAIN
   DEFINE x CHAR(20),
          y CHAR(50)
   LET x = "String 1 "
   LET y = "Concatenou ",x CLIPPED," com outras duas strings"
   DISPLAY y
END MAIN 

RESULTADO
Concatenou String 1 com outras duas strings 

Exemplo de concatenação de strings

...

O 4GL apesar de ser uma linguagem de 4ª geração possui esta capacidade das linguagens estruturadas.

 

FUNCTION nome_da_funcao([arg1,arg2,...,argn])
  instrução
  ...
  [RETURN lista_expressões]
  ...
END FUNCTION

Definição genérica de uma função

...

 

olafuncao.4gl

MAIN
   CALL funcao_ola()
END MAIN

FUNCTION funcao_ola()
  DISPLAY "Olá mundo!"
END FUNCTION 

 RESULTADO:
 Olá mundo! 

Uma função simples

Numa função, além de poder ter variáveis locais, pode ainda ter variáveis de entrada (parâmetros), e, ter associação valores a serem retornados á função que a invocou (valores de retorno). Tanto os parâmetros como os valores de retorno podem ser de qualquer tipo permitido pelo 4gl. A chamada da função faz-se com a instrução CALL e para definir em que variáveis são atribuídos os valores devolvidos usa-se a cláusula RETURNING com uma lista de variáveis a retornar.

 

CALL função([argumentos]) [RETURNING lista_de_variáveis]

Definição genérica da instrução CALL

Se uma função devolver apenas um valor pode-se chamar com a instrução LET.

 

LET variavel = função([argumentos])

Chamar uma função com instrução LET

Os parâmetros de uma função são sempre declarados. Esta declaração faz com que a linguagem verifique todas as chamadas ás funções e no caso destas não serem executadas com o mesmo número de parâmetros que a declaração da função resulta em um erro de compilação do programa.

 

max.4gl

MAIN
   DEFINE maxval INTEGER
   LET maxval = maximo(4,8,5)
   DISPLAY "O maior numero e: ",maxval
END MAIN

FUNCTION maximo(n1,n2,n3)
  DEFINE n1 INTEGER,
         n2 INTEGER,
         n3 INTEGER

IF n1 > n2 THEN
      LET n2 = n1
  END IF
  IF n2 > n3 THEN
     RETURN n2
END IF

RETURN n3

END FUNCTION

RESULTADO:
O maior numero e: 8 

Função com vários tipos de parâmetros de entrada

...

Ao contrário de algumas linguagens de terceira geração (por exemplo o C), uma função de 4GL não necessita ser declarada como um determinado tipo, ou seja, se pretender que a função devolva o número inteiro 10, só terá que retornar um valor de tal tipo:

 

retfunc1.4gl

MAIN
   DEFINE x INTEGER
   LET x = FUNC()
   DISPLAY "X tem",x
END MAIN

FUNCTION FUNC()
  RETURN 10
END FUNCTION

RESULTADO:
 X tem 10 

Função que retorna um número inteiro

...

 

retfunc2.4gl

MAIN
   DEFINE x CHAR(100)
   LET x = FUNC()
   DISPLAY x
END MAIN

FUNCTION FUNC()
  RETURN "Esta string vai ser devolvida"
END FUNCTION

RESULTADO:
Esta string vai ser devolvida 

Função que retorna uma string

É preciso ter cuidado para que a variável em que se atribui o retorno da função seja do mesmo tipo do valor (ou variável) retornado dentro da função.

 

retfunc3.4gl

MAIN
   DEFINE x INTEGER
          y CHAR(100)

   CALL func() RETURNING x,y

   DISPLAY x
   DISPLAY y

END MAIN

FUNCTION func()
  RETURN 100,"Esta string vai ser devolvida"
END FUNCTION

RESTULTADO:
 100
 Esta string vai ser devolvida

Função com retorno de vários valores

...

Em português esta instrução poderia ser explicada por:

  

 

 Se Se esta expressão é verdadeira
    Então faz isto
 Senão Senão faz aquiloaquilo 

 

 

 

Em que "faz isto" e "faz aquilo" seria um conjunto de instruções a executar em cada um dos casos.

 

 

 

 IF expressão_booleana THEN
    instrução
 [ELSE
    instrução]
 END IF 

 

...

 Definição geral da instrução IF...THEN...ELSE

Uma expressão booleana pode, por exemplo, ser um conjunto de comparações entre expressões, sendo possível realizar operações booleanas entre expressões, nomeadamente:

...

AND     A expressão é verdadeira se todas as sub-expressões também forem verdadeiras.

 

 

 

 IF IF a = "casado" AND b = "solteiro" THEN
    CALL casa_com(a,b)
 END END IF 

 

Utilização de AND numa expressão

OR       A expressão é verdadeira se pelo menos uma das sub-expressões for verdadeira.

 

 

 

 IF IF cao = "morde" OR cao = "grande" THEN
    CALL correr_mais_depressa()
 END END IF 

 

Utilização de OR numa expressão

NOT     A expressão é verdadeira se a sub-expressão não o for.

 

 

 

 IF IF NOT ha_cerveja THEN
    CALL bebe_vinho()
 END END IF 

 

Utilização de NOT numa expressão

3.2      WHILE

Esta instrução de repetição pode ser explicada por:

   

 

 

 Enquanto Enquanto esta_expressão_for_verdadeira faz_isto

 

 

...

isto 

 

WHILE é um conjunto de instruções a serem executadas se a expressão booleana for verdadeira.

 

...

 

 WHILE expressao_booleana
    {instrução | EXIT WHILE | CONTINUE WHILE}
 END WHILE 

 

Definição genérica da instrução WHILE

Uma expressão booleana usada no WHILE é idêntica a usada no IF e a qualquer outra que se utilize num programa.

 

 

 

 WHILE WHILE esta <> "bebado"
    CALL bebe_mais_cerveja()
 END WHILE

 

 

Ciclo WHILE

Existem duas instruções que podem ser usadas dentro de um WHILE:

-          EXIT WHILE
-          CONTINUE WHILEWHILE 

 

EXIT WHILE, serve para abandonar o ciclo independentemente da expressão booleana do WHILE.

...

As vezes é necessário executar um ciclo por um determinado número de vezes, incrementando uma variável com um valor.

 

 

 

 FOR FOR variavel_inteira = expressão1 TO expressao2
    [STEP expressão3 ]
    {instrução | CONTINUE FOR | EXIT FOR}
 END END FOR 

 Definição genérica do ciclo FOR

A instrução acima definida inicializa a variavel_inteira com o resultado da expressão1 e cumpre as instruções até que a expressão2 seja falsa, incrementando a variável_inteira com o resultado de expressão3. Se o programador, por alguma razão desejar sair do ciclo, pode utilizar a instrução EXIT FOR. Se, por outro lado já não pretender executar as instruções abaixo e continuar a partir do próximo ciclo, pode utilizar a instrução CONTINUE FOR. Estas duas ultimas instruções são análogas às instruções existentes no ciclo WHILE, incidindo no entanto somente sobre o comando FOR.

...

As vezes é necessário tomar uma decisão múltipla, isso pode ser feito com uso de várias instruções IF agrupadas. A instrução CASE surge como uma forma mais simples de resolver esta questão.

 

 

 

 CASE CASE [(expressão)]
    WHEN {expressão | expressão booleana}
           instrução
       ...
    [EXIT CASE]
           ....
 [OTHERWISE]
         instrução
      ...
    [EXIT CASE]
      ...
 END END CASE

 

 

Definição genérica da instrução CASE

A instrução CASE pode ser utilizada de duas formas diversas:

-          Por expressões;
-          Por expressões booleanas.

3.4.1       SELEÇÃO REALIZADA POR EXPRESSÕES

 

...

 

 CASE (expr)
 WHEN valor
    instrução
    ...
 OTHERWISE
    instrução
         ...
 END CASE 

 Forma geral de CASE com seleção por expressões

A expressão é comparada com os vários valores, sendo executadas as instruções associadas ao primeiro valor igual ao resultado da expressão. Se todos os valores forem diferentes do resultado da expressão, são executadas as instruções associadas á cláusula OTHERWISE, se esta existir.

 

 

 

  case1case1.4gl

 DATABASE livrosDATABASE livros  

MAIN

 MAIN

   DEFINE x    LIKE livros.numero,
          ans  CHAR(1),
          nome LIKE livros.nome

 

   LET ans = "s" 

   WHILE 1
              PROMPT "Qual o numero do livro que pretende   procurar: " FOR

      SELECT livros.nome
        INTO nome
        FROM livros
               WHERE numero = x

    

      DISPLAY nome

x   

   DISPLAY nome 
      PROMPT "Quer escolher mais livros (S/N) " FOR CHAR ansans 

 

      CASE (ans)
      WHEN "s"
         EXIT CASE
      WHEN "n"
         EXIT WHILE
      OTHERWISE      OTHERWISE
         DISPLAY "OPCAO INVALIDA"
         EXIT WHILE
      END CASE
   END WHILE
 END MAINEND MAIN 

 

 $ fglpc case1.4gl
 $ fglgo case1.4go
 Qual o numero do livro que pretende procurar: 34
 Quer escolher mais livros (S/N) g
 OPCAO INVALIDA 

 Utilização do CASE utilizando expressões para fazer a seleção

Na execução deste programa, quando se perguntou ao usuário se desejava procurar mais livros, ele respondeu a letra <g> quando as opções válidas eram <s> ou <n> e neste caso o programa entrou na cláusula OTHERWISE do CASE.

...

A instrução CASE com expressões booleanas toma a seguinte forma: 

 

 

 CASE
 WHEN expressão_booleana1
    instrução
    ...
 WHEN expressão_booleana2
    instrução
    ...
 OTHERWISE
    instrução
    ...
 END CASE 

 Instrução CASE com seleção por expressão booleana

As expressões booleanas são avaliadas na ordem em que aparecem e é executado o grupo de instruções associado á primeira expressão booleana verdadeira. Se todas as expressões forem falsas são executadas as instruções associadas á cláusula OTHERWISE.

Em qualquer das formas da instrução CASE pode-se incluir no bloco de instruções uma instrução EXIT CASE que provoca a interrupção do CASE neste ponto.

 

 

 

  case2case2.4gl MAIN

MAIN
   DEFINE x    SMALLINTSMALLINT 

 

   LET x = 5000
   CASE
   WHEN x < 1000
      DISPLAY “X é menor que 1000”
   WHEN x >= 1000 AND x <= 5000
      DISPLAY “X está entre 1000 e 5000”
   WHEN x > 5000
      DISPLAY “X é maior que 5000”
   OTHERWISE
      DISPLAY “Valor inválido para X”
   END CASE
 END END MAIN

 

 $ $ fglpc case1.4gl
 $ $ fglgo case1.4go
 X X está entre 1000 e 5000

 

 

Utilização do CASE utilizando expressões para fazer a seleção

4       BIBLIOTECA 4GL

Este capítulo descreve as funções que estão disponíveis na biblioteca do INFORMIX-4GL. Qualquer uma das funções apresentadas em seguida podem ser chamadas num programa, que o compilador automaticamente linka ao programa.

...

Suponhamos que o nosso programa de 4GL compilado se chame teste.4go.Ao executá-lo a partir da linha de comando fazemos:

 

...

 

fglgo teste Maria Pedro Catarina 

 

Execução de um programa de 4GL, com argumentos

O programa que se segue é um exemplo, recebe os nomes num ARRAY de variáveis do tipo CHAR

 ARR_COUNT()

Esta função devolve o número de linhas introduzidas num ARRAY de um programa durante ou após a instrução INPUT ARRAY.

Quando se executa uma instrução com a cláusula BEFORE, AFTER ou ON KEY, o valor de ARR_CURR, SCR_LINE ou ARR_COUNT, é alterado, e o valor resulta da execução das cláusulas.

 

 

 

 FUNCTION FUNCTION inserir_livros()
  DEFINE contador SMALLINTSMALLINT 

    FOR contador = 1 TO arr_count()
     INSERT INTO livros
     VALUES (ma_livros[contador].liv_num,
             ma_livros[contador].liv_nome,
             ma_livros[contador].liv_editora,
             ma_livros[contador].liv_no)
  END FOR
 END FUNCTION

 

 

Exemplo de utilização da função ARR_COUNT

ARR_CURR()

Esta função devolve a linha do ARRAY do programa que corresponde à linha do ARRAY corrente da tela durante ou imediatamente após a instrução INPUT ARRAY ou DISPLAY ARRAY.

...

A primeira linha tanto do ARRAY do programa ou da tela é numerada a partir de 1.

 

 

 

 INPUT INPUT ARRAY ma_livros TO sr_livros.*
 ON KEY(F6)
   DISPLAY ARRAY ma_estante TO sr_estante.*
   END DISPLAY
   LET l_arr_curr = ARR_CURR()
   MESSAGE "O valor corrente de ARR_CURR é: ", l_arr_curr

 END INPUT

 

 

END INPUT 

Exemplo da utilização da função ARR_CURR

DOWNSHIFT(frase)

Esta função devolve uma string em que todos os caracteres que lhe tenham sido passados em letras maiúsculas sejam convertidos em minúsculas.

...

A função DOWNSHIFT pode ser usada numa expressão ou para atribuição a uma variável com o valor devolvido pela função.

 

 

 

 LET LET l_str = DOWNSHIFT(l_str)
 DISPLAY   DISPLAY l_str str 

 Exemplo de utilização da função DOWNSHIFT

UPSHIFT(frase)

Esta função devolve uma string em que todos os caracteres que lhe tenham sido passados em letras minúsculas sejam convertidos em maiúsculas.

...

A função UPSHIFT pode ser usada numa expressão ou para atribuição a uma variável com o valor devolvido pela função.

 

 

 

 LET LET l_str = UPSHIFT(l_str)
 DISPLAY l_str str 

 Exemplo de utilização da função UPSHIFT

ERR_GET(expressão)

Esta função devolve uma variável do tipo CHAR que contém a mensagem de erro, correspondente ao código enviado como argumento.

...

A utilização desta função é muito importante durante as operações de debug.

 

 

 IF IF status < 0 THEN
    LET errtext = ERR_GET(status)

 END IF

 END IF 

 Exemplo de utilização da função ERR_GET

...

ERR_PRINT(expressão)

Esta função escreve a mensagem de erro do INFORMIX-4GL, correspondente ao seu argumento, na ERROR LINE (linha de erro).

...

A utilização desta função é muito importante durante as operações de debug.

 

 

 

 IF IF status < 0 THEN
    LET errtext = ERR_PRINT(status)

 END IF

 

 

END IF 

Exemplo de utilização da função ERR_PRINT

 

ERR_QUIT(expressão)

Esta função escreve a mensagem de erro do INFORMIX-4GL, correspondente ao seu argumento, na ERROR LINE (linha de erro) e interrompe a execução do programa.

 

 

 

 

 CALL CALL ERR_QUIT(expressão) 

 

Formato da função ERR_QUIT

Geralmente a expressão é a variável global STATUS ou SQLCA.SQLCODE.

A utilização desta função é muito importante durante as operações de debug.

 

 

 

 IF IF status < 0 THEN
    CALL ERR_QUIT(status)

 END IF

 

 

END IF 

Exemplo de utilização da função ERR_QUIT

5       Comandos básicos para entrada/saída de dados

...

A definição genérica de uma instrução PROMPT é a seguinte:

 

...

 PROMPT mensagem FOR [CHAR] variável
        [HELP numero_do_help]
        [ON KEY (tecla)
   instrução
   ...
   ...
 END END PROMPT

Definição genérica da instrução PROMPT

...

Se a instrução for invocada com a palavra chave CHAR, o programa não espera pela tecla <NEW LINE>, o que equivale a dizer que aceita o caracter e sai da instrução PROMPT assim que é pressionada uma tecla. 

 

 

  prompt.4gl

 DATABASE livros

 

 MAIN

   DEFINE x LIKE livros.numero,

   ans CHAR(1),

   nome LIKE livros.nome

 

   LET ans = "s"

 

   WHILE (ans = "s" OR ans = "S")

      PROMPT "Qual o numero do livro que pretende procurar: " FOR x

 

      SELECT livros.nome

        INTO nome

        FROM livros

       WHERE numero = x

 

      DISPLAY nome

 

      PROMPT "Quer escolher mais livros (S/N) " FOR CHAR ans

   END WHILE

 END MAIN

 

 $ fglpc prompt.4gl

 $ fglgo prompt.4go

 Qual o numero do livro que pretende procurar: 15

 Microsoft C Compiler

 Quer escolher mais livros (S/N) n

 

 

...

NOME

TIPO

DESCRIÇÃO

*livro

integer

Número de identificação do livro

*entidade

integer

Identificação da entidade requisitante

                           Estrutura da tabela requisições

A tabela entidades tem os dados gerais de cada entidade. A sua estrutura é a seguinte:

...