Utilizar associações em expressões de caminho

Objectives

After completing this lesson, you will be able to:
  • Utilize expressões de caminho em visões CDS.
  • Use condições de filtro em expressões de caminho.
  • Use expressões de caminho no ABAP SQL.

Expressões de caminho em CDS

Quando uma entidade de visão CDS lê a partir de uma entidade com associações expostas, existem duas possibilidades:

Propagando a associação

Ao adicionar o nome da associação à lista de elementos, a associação também se torna visível para os consumidores dessa visão. No exemplo, a associação _Department é definida e exposta na entidade de visão R_Employee. Visualizar entidade C_Employee lê de R_Employee e propaga associação _Department.

Usando a associação

Ao adicionar um sinal de período (.) e um nome de elemento após o nome da associação, a associação é usada para ler dados do destino de associação. Esse tipo de uso é chamado de Expressão de caminho. No exemplo, o destino da associação _Department é a entidade de visão CDS C_Department. A entidade de visão CDS C_Employee utiliza uma expressão de caminho para ler o campo DepmentDesignation do destino de associação e o adiciona à sua própria lista de elementos.

No nível do banco de dados, uma expressão de caminho é convertida em uma junção da origem da associação e do destino da associação. Isso se torna visível na função Mostrar instrução SQL Create do editor.

No exemplo, a expressão de caminho _Department.DepmentDesignation leva a um join de visões SQL R_EMPLOYEE e R_DEPARTMENT no banco de dados. A condição ON para o join é derivada da condição ON da associação.

Nota

O tipo de junção LEFT OUTER MANY TO ONE JOIN é uma especialidade do banco de dados SAP HANA. Também existe um tipo de junção LEFT OUTER MANY TO MANY JOIN que é utilizado quando a cardinalidade de associação tem um máximo superior a 1.

É importante ressaltar que o join no nível do banco de dados só é construído quando a associação é utilizada em uma expressão de caminho. Definir, expor e propagar uma associação não leva a uma junção. Esse recurso de associações às vezes é referido como Join on Demand.

Vejamos um exemplo novamente: mesmo que a entidade de visão CDS R_Employee defina e exponha a associação _Department e a entidade de visão CDS C_Employee propaga essa associação, a visão SQL correspondente C_EMPLOYEE lê somente a partir da visão SQL R_EMPLOYEE.

Até agora, discutimos expressões de caminho com uma associação, apenas. Mas você também pode criar expressões de caminho mais longas encadeando várias associações.

Aqui está um exemplo: a entidade de visão CDS R_Employee expõe a associação _Department, que tem a entidade de visão CDS R_Department como destino. Este destino expõe outra associação _Head, apontando de volta para R_Employee, mas lendo o empregado que é chefe do respectivo departamento. Caminho expressão _Department._Head.LastName lê o sobrenome do chefe do departamento ao qual um empregado está atribuído. A junção longa e complicada de três fontes de dados é gerada automaticamente.

Na maioria das vezes, quando uma entidade de visão CDS define uma associação, ela a expõe a seus consumidores. No entanto, também pode utilizar a associação, diretamente, em vez de ou além de expô-la.

Chamamos isso de uso ad-hoc de associações. No exemplo, a entidade de visão CDS R_Employee define a associação _Department. Em vez de expor a associação, ela a utiliza diretamente em uma expressão de caminho para recuperar a designação do departamento relacionado.

No caso de uma utilização ad hoc, a junção é criada imediatamente na visão SQL para essa entidade de visão CDS.

Como escrever expressões de caminho no CDS

Assista ao vídeo para ver como escrever expressões de caminho no CDS.

A influência da cardinalidade nas expressões de caminho

Quando você utiliza uma associação em uma expressão de caminho, a cardinalidade pode influenciar a verificação de sintaxe. O editor exibe avisos e até mesmo erros para a utilização incorreta de associações "para muitos", ou seja, associações para as quais a cardinalidade tem um máximo maior que 1.

Em expressões de caminho na cláusula WHERE da definição de visão, a utilização de associações "para muitas" não é permitida e leva a um erro de sintaxe.

Na lista de elementos, são permitidas associações "para muitos", mas o editor exibe um aviso, indicando que essa expressão de caminho pode modificar o número de conjuntos de resultados.

O que significa este aviso? Imagine que suas tabelas contenham apenas 1 departamento com 5 funcionários. Sem a expressão de caminho, a visão CDS C_Department retorna exatamente 1 conjunto de dados. Em seguida, você adiciona a expressão de caminho com a associação "para muitos" _Employee à lista de elementos. Depois disso, a mesma visão retorna 5 conjuntos de dados, um para cada empregado. Isso pode ser enganoso para os consumidores da visão C_Department porque eles esperam um conjunto de dados para cada departamento.

Dica

Se você estiver interessado em uma combinação de dados do empregado e dados do departamento, deve iniciar a partir da visão R_Employee e utilizar a associação "to one" _Department para adicionar os detalhes do departamento.

Uma forma de usar uma associação "para muitos" corretamente é colocar a expressão de caminho dentro de uma agregação. A cláusula GROUP-BY-, que é obrigatória para agregações, garante que o número de conjuntos de dados permanece o mesmo. No exemplo, a entidade de visão CDS C_Department ainda retorna um conjunto de dados por departamento e não um conjunto de dados por empregado.

Nota

Outra forma de usar corretamente uma associação "para muitos" é a adição de uma condição de filtro. Discutiremos filtros na próxima seção.

Experimente: Uso incorreto e correto de associações 'para muitos'

  1. Crie uma nova definição de dados CDS com /DMO/I_Connection_R como objeto de dados referenciado.
  2. Remova a lista de elementos, incluindo as chaves circundantes.
  3. Copie o seguinte snippet de código e insira-o após as select from /DMO/I_Connection_R:
    Code Snippet
    123456789101112131415161718192021
    { key AirlineID, key ConnectionID, // _Airline.CurrencyCode, // _Flight.PlaneType, DepartureAirport, DestinationAirport } where AirlineID = 'LH' // Only one connection and ConnectionID = '0400' // fulfills this filter // and _Airline.CurrencyCode = 'EUR' // and _Flight.PlaneType = '747-400'
  4. Ative a definição de dados e exiba a visualização de dados. Como a cláusula WHERE qualifica completamente a chave primária das conexões de voo, você só vê um conjunto de dados.
  5. Remova os marcadores de comentário das duas expressões de caminho na lista de elementos. Observe o aviso de sintaxe porque _Flight tem cardinalidade 0..* e, portanto, é uma associação "para muitos".
  6. Ative a definição de dados apesar do aviso e exiba a visualização de dados. Agora você vê vários conjuntos de dados.
  7. Comente as condições adicionais na cláusula WHERE. Observe o erro de sintaxe para a expressão de caminho que inclui a associação _Flight.
  8. Remova a lista de elementos e a cláusula WHERE e substitua-a pela seguinte sintaxe:
    Code Snippet
    1234567891011121314151617
    { key AirlineID, key ConnectionID, _Flight.OccupiedSeats // sum(_Flight.OccupiedSeats) as TotalOccupiedSeats } where AirlineID = 'LH' // Only one connection and ConnectionID = '0400' // fulfills this condition // group by // AirlineID, // ConnectionID
  9. Observe o aviso de sintaxe para a expressão de caminho, incluindo a associação _Flight. Ative e exiba a visualização de dados.
  10. Comente a expressão de caminho e remova os marcadores de composição da função agregada sum( ) e da cláusula GROUP BY. Observe que o aviso de sintaxe desapareceu e que a visualização de dados exibe somente um conjunto de dados.

Filtros em expressões de caminho

Quando você usa uma associação em uma expressão de caminho, pode adicionar filtros para restringir os conjuntos de dados do destino de associação. A condição de filtro é colocada em um par de colchetes ([ ]) imediatamente após o nome da associação. Como em uma cláusula WHERE, você pode usar operadores relacionais e operadores booleanos AND, OR, NOT. O lado esquerdo de uma condição deve ser um campo do destino da associação. Para o lado direito, há mais flexibilidade. Entre outras coisas, você pode utilizar campos do destino de associação, literais, funções integradas, etc.

No exemplo, existem duas expressões de caminho, uma sem uma condição de filtro e a outra com condição de filtro OccupiedSeats > MaximumSeats. Enquanto a primeira expressão de caminho procura o primeiro voo associado a uma conexão de voo, a segunda expressão de caminho restringe a pesquisa a voos ocupados, ou seja, voos em que o número de assentos ocupados excede o número de assentos disponíveis.

Tecnicamente, a condição de filtro é adicionada à condição ON da junção gerada no nível do banco de dados.

Vejamos a instrução SQL create para nosso exemplo: a primeira junção em nosso exemplo pertence à expressão path sem o filtro. A condição ON compara AIRLINEID, CONNECTIONID e o campo de cliente MANDT. A segunda junção pertence à expressão de caminho com o filtro. Você consegue identificar a condição adicional da expressão de caminho filtrada?

Quando você filtra uma associação que tem uma cardinalidade com máx. > 1, pode acontecer que, depois de aplicar o filtro, permaneça somente uma entrada do destino de associação. O filtro transforma a associação "para muitos" em uma associação "para um". Em uma situação desse tipo, você deve adicionar "1: " na frente da condição do filtro para documentar a cardinalidade modificada da associação.

Neste exemplo, a entidade de visão CDS I_Currency define e expõe a associação _Text, que é uma associação "para muitos", retornando nomes de moeda em diferentes idiomas. Sem um filtro, a associação leria o nome de uma moeda em todos os idiomas atualizados no sistema. No entanto, as duas expressões de caminho com um filtro leem somente um nome de moeda, em inglês ou em alemão.

Como vimos anteriormente, a verificação de sintaxe emite avisos e erros quando usamos uma associação "para muitos" em uma expressão de caminho que está fora de uma agregação. Mas o que acontece se um filtro garantir que existe apenas um registro? A verificação de sintaxe ainda emite os avisos e erros? Sim, ele faz, porque não pode saber que o filtro transforma a associação "para muitos" em uma associação "para um". Podemos documentar isso adicionando "1:" dentro dos colchetes, antes da condição de filtro. No exemplo, existe um aviso de sintaxe para a expressão de caminho com o filtro Language = 'E'. Mas não existe nenhum aviso de sintaxe para a expressão de caminho com o filtro 1: Language = 'D'.

Testar: associações filtradas

  1. Crie uma nova definição de dados CDS com /DMO/I_Connection_R como objeto de dados referenciado.
  2. Remova a lista de elementos, incluindo as chaves circundantes.
  3. Copie o seguinte snippet de código e insira-o após as select from /DMO/I_Connection_R:
    Code Snippet
    123456789101112131415
    { key AirlineID, key ConnectionID, //_Airline._Currency._Text.CurrencyName //_Airline._Currency._Text[ Language = 'E' ].CurrencyName //_Airline._Currency._Text[ 1: language = 'E' ].CurrencyName } where AirlineID = 'AA' and ConnectionID = '0017'
  4. Remova os marcadores de comentário da primeira expressão de caminho e analise os avisos de sintaxe (se existirem).
  5. Ative a definição de dados e exiba a visualização de dados e a instrução SQL de criação para esta versão da visão.
  6. Comente a primeira expressão de caminho e remova os marcadores de comentário da segunda expressão de caminho.
  7. Ative e analise os avisos de sintaxe, a visualização de dados e a instrução SQL create para a expressão de caminho que inclui um filtro.
  8. Repita com a terceira expressão de caminho.

Expressões de caminho no ABAP SQL

Outra forma de usar associações expostas são as expressões de caminho no ABAP SQL. O conceito é exatamente o mesmo que no CDS, mas a sintaxe é ligeiramente diferente.

As diferenças de sintaxe mais importantes são as seguintes:

Prefixo de associação

Nas expressões de caminho ABAP SQL, as associações devem ser escapadas com uma barra invertida (\).

Seletor de elementos

Em expressões de caminho CDS, um sinal de ponto (.) é utilizado como separador entre o nome da associação e o nome do elemento. No ABAP SQL, o sinal do período não é adequado porque encerraria a instrução. Portanto, no ABAP SQL, um hífen é usado como seletor de elementos.

Vejamos um exemplo: esta instrução SELECT ABAP SQL lê a partir da entidade de visão CDS /DMO/I_Connection_R que expõe uma associação _Airline. A última expressão na lista FIELDS é uma expressão de caminho para ler o nome do elemento a partir do destino de associação /DMO/I_Carrier.

Outra diferença de sintaxe está relacionada a associações encadeadas. Quando uma expressão de caminho contém uma sequência de associações, não existe um separador dedicado. Em que no CDS as associações são separadas por um sinal de ponto (.), elas se seguem diretamente no ABAP SQL. No entanto, considere que cada nome de associação precisa de uma barra invertida (\) como prefixo.

Neste exemplo, o destino da associação _Airline expõe uma associação _Currency que retorna detalhes para a moeda local da companhia aérea. A expressão \_Airline\_Currency-CurrencyISOCode lê o código ISO para a moeda local da companhia aérea que opera a conexão de voo.

Nota

No CDS, a mesma expressão de caminho lê _Airline._Currency.CurrencyISOCode.

No ABAP SQL, as condições de filtro são adicionadas entre colchetes, como no CDS. No entanto, para indicar uma cardinalidade, é usada uma sintaxe totalmente diferente. Em vez de "1:", você tem que adicionar palavras-chave MANY TO ONE WHERE. Existem várias outras opções, como ONE TO ONE WHERE e MANY TO MANY WHERE. Consulte a documentação de palavra-chave ABAP para obter detalhes.

Nota

Existe uma sintaxe alternativa em que você escreve [(1) WHERE … ] em vez de [ MANY TO ONE WHERE … ], mas essa sintaxe alternativa não é recomendada.

Testar: expressões de caminho no ABAP SQL

  1. Crie uma nova classe global que implemente a interface IF_OO_ADT_CLASSRUN.
  2. Copie o seguinte snippet de código para a parte de implementação do método if_oo_adt_classrun~main( ):
    Code Snippet
    1234567891011121314151617181920212223242526272829303132333435
    * Data selection ********************************************************************** SELECT FROM /dmo/i_connection_R FIELDS Airlineid, connectionid, * _Airline.Name, * \_Airline-Name, * _Airline-Name, * _Airline~Name, * \_Airline~Name, * * \_Airline-_Currency-CurrencyISOCode, * \_Airline-\_Currency-CurrencyISOCode, * \_Airline\_Currency-CurrencyISOCode, * \_Airline~\_Currency~CurrencyISOCode, * \_Airline\_Currency~CurrencyISOCode, * * \_Airline\_Currency\_Text[ Language = 'E' ]-CurrencyShortName AS CurrencyNameEN, * \_Airline\_Currency\_Text[ MANY TO ONE WHERE Language = 'D' ]-CurrencyShortName AS CurrencyNameDE, * \_Airline\_Currency\_Text[ Language = 'E' ]-CurrencyShortName AS CurrencyNameEN, * \_Airline-\_Currency-\_Text[ MANY TO ONE WHERE Language = 'D' ]-CurrencyShortName AS CurrencyNameDE, * \_Airline~\_Currency~\_Text[ 1: Language = 'E' ]-CurrencyShortName AS CurrencyNameEN, DepartureAirport, DestinationAirport INTO TABLE @DATA(result). * Output ********************************************************************** out->write( data = result name = 'Selection result').

    Essa codificação contém uma instrução SELECT do ABAP SQL com várias expressões de caminho.

  3. Remova o comentário do primeiro bloco de expressões de caminho e utilize a verificação de sintaxe para encontrar uma expressão de caminho sintaticamente correta no ABAP SQL.
  4. Remova as variantes sintaticamente erradas, ative a classe, execute-a como aplicativo de console e analise a saída do console.
  5. Repita isso com o segundo e o terceiro bloco de expressões de caminho.

Utilizar associações em expressões de caminho

Você definiu entidades de visão CDS com associações expostas. Você quer usar as associações expostas. Primeiro, você faz isso em uma visão CDS e, em seguida, em uma instrução SELECT no ABAP SQL.

Modelo:

  • /LRN/CL_S4D430_RLT_PATH_EXP (classe global)

Solução:

  • /LRN/C_EMPLOYEE_QRY (Definição de dados)
  • /LRN/CL_S4D430_RLS_PATH_EXP (classe global)

Tarefa 1: Utilizar associações expostas em CDS

Defina uma nova entidade de visão CDS (nome sugerido: Z##_C_EmployeeQuery). Como fonte de dados, utilize sua entidade de visão para dados do empregado que expõe uma associação (o nome sugerido era: Z##_R_Employee). Na lista de elementos, leia o ID e o nome do empregado. Em seguida, adicione expressões de caminho para ler a descrição do departamento e o sobrenome do assistente de departamento.

Nota

Se você não tiver concluído o exercício anterior, pode permitir que sua nova entidade de visão leia a partir da entidade de visão /LRN/R_Employee_Rel.

Etapas

  1. Em seu próprio pacote, crie uma nova definição de dados (nome sugerido: Z##_C_EMPLOYEEQUERY, em que ## é o número do seu grupo). Indique sua entidade de visão CDS Z##_R_Employee como objeto referenciado e selecione o modelo Definir entidade de visão para gerar a declaração de definição, algumas anotações padrão e a lista de elementos.

    1. Na visão Explorador de projetos, clique com o botão direito do mouse em sua definição de dados Z##_R_EMPLOYEE para abrir o menu de contexto.

    2. No menu de contexto, selecione Nova definição de dados.

    3. Confirme que o campo Pacote contém o nome do seu pacote e que o campo Objeto referenciado contém o nome da sua definição de tabela de banco de dados.

    4. No campo Nome, insira o nome para a entidade da visão CDS (Z##_C_EmployeeQuery, em que ## é o seu número de grupo).

    5. Insira Empregado (consulta) no campo Descrição e selecione Seguinte.

    6. Confirme a ordem de transporte e selecione Seguinte.

      Cuidado

      Certifique-se de que você ainda não selecionou Concluir. Se fizer isso, você não poderá escolher o modelo que deseja usar.
    7. A partir da lista de modelos, selecione Definir entidade de visão e, em seguida, selecione Concluir.

  2. Aplique a formatação do código-fonte.

    1. No menu eclipse, selecione Formato→do texto fonte. Como alternativa, selecione Shift + F1.

  3. Edite a lista de elementos da nova definição de dados. Remova todos os elementos, exceto EmployeeID, FirstName, LastName, DepartmentID e a associação exposta _Department.

    1. Ajuste o código da seguinte forma:

      Code Snippet
      1234567891011121314
      define view entity Z##_C_EmployeeQuery as select from Z##_R_Employee { key EmployeeId, FirstName, LastName, DepartmentID, /* Associations */ _Department }
  4. Após o elemento DepartmentID, adicione uma expressão de caminho para ler a descrição do departamento ao qual o funcionário está atribuído (nome do elemento sugerido: DepartmentDescription).

    1. Ajuste o código da seguinte forma:

      Code Snippet
      12345678910111213141516
      define view entity Z##_C_EmployeeQuery as select from Z##_R_Employee { key EmployeeId, FirstName, LastName, DepartmentID, _Department.Description as DepartmentDescription, /* Associations */ _Department }
  5. Grave a definição de dados e exiba a instrução SQL CREATE.

    Nota

    Se você não salvar a definição de dados, suas alterações não serão exibidas na instrução SQL CREATE.
    1. Pressione Ctrl + S para salvar o objeto de desenvolvimento.

    2. Clique com o botão direito do mouse em qualquer lugar no texto fonte da definição de dados e selecione Mostrar instrução SQL CREATE.

  6. Adicione uma expressão de caminho para ler o sobrenome do assistente de departamento (nome do elemento sugerido: AssistantName).

    1. Ajuste o código da seguinte forma:

      Code Snippet
      1234567891011121314151617
      define view entity Z##_C_EmployeeQuery as select from Z##_R_Employee { key EmployeeId, FirstName, LastName, DepartmentID, _Department.Description as DepartmentDescription, _Department._Assistant.LastName as AssistantName, /* Associations */ _Department }
  7. Ative a definição de dados e exiba novamente a instrução SQL CREATE.

    1. Pressione Ctrl + F3 para ativar o objeto de desenvolvimento.

    2. Clique com o botão direito do mouse em qualquer lugar no texto fonte da definição de dados e selecione Mostrar instrução SQL CREATE.

  8. Exiba o resultado da consulta na ferramenta Visualização de dados.

    1. Posicione o cursor em qualquer lugar na definição de dados e pressione F8 para chamar a ferramenta Visualização de dados.

Tarefa 2: Usar associações expostas no ABAP SQL

Crie uma cópia da classe ABAP /LRN/CL_S4D430_RLT_PATH_EXPR (nome sugerido: ZCL_##_PATH_EXPR) e ajuste a instrução SELECT. Leia todos os campos da entidade de visão CDS que você acabou de criar (nome sugerido: Z##_C_EmployeeQuery). Além disso, implemente uma expressão de caminho no ABAP SQL para ler o nome do chefe de departamento.

Etapas

  1. Copie a classe /LRN/CL_S4D430_RLT_PATH_EXPR para uma classe em seu próprio pacote (nome sugerido: ZCL_##_PATH_EXPR, em que ## é para seu número de grupo).

    1. Na visão Explorador de projetos, clique com o botão direito do mouse na classe /LRN/CL_S4D430_RLT_PATH_EXP para abrir o menu de contexto.

    2. No menu de contexto, selecione Duplicar ....

    3. Insira o nome do seu pacote no campo Pacote. No campo Nome, insira o nome ZCL_##_PATH_EXP, em que ## é seu número de grupo.

    4. Ajuste a descrição e selecione Seguinte.

    5. Confirme a ordem de transporte e selecione Concluir.

  2. No método IF_OO_ADT_CLASSRUN~MAIN, modifique a instrução SELECT. Substitua /LRN/C_Employee_Ann na cláusula FROM pelo nome da entidade de visão CDS que você acabou de criar (Z##_C_EmployeeQuery).

    1. Ajuste o código da seguinte forma:

      Code Snippet
      123456
      SELECT FROM Z##_C_EmployeeQuery FIELDS employeeid,
  3. No final da lista de campos, leia também os novos elementos de visão DepartmentDescription e AssistantName.

    1. Ajuste o código da seguinte forma:

      Code Snippet
      1234567891011
      SELECT FROM Z##_C_EmployeeQuery FIELDS employeeid, firstname, lastname, departmentid, departmentdescription, assistantname INTO TABLE @DATA(result).
  4. Após o nome do assistente de departamento, implemente uma expressão de caminho que leia o sobrenome do chefe de departamento (nome de campo sugerido: HEADNAME).

    Dica

    Utilize a conclusão de código sempre que possível. Lembre-se de que, no ABAP SQL, os nomes de associação necessitam de um sinal de barra invertida (\) como prefixo e que um sinal de hífen (-) é usado entre o nome da associação e o nome do elemento.
    1. Ajuste o código da seguinte forma:

      Code Snippet
      123456789101112
      SELECT FROM Z##_C_EmployeeQuery FIELDS employeeid, firstname, lastname, departmentid, departmentdescription, assistantname, \_department\_head-lastname AS headname INTO TABLE @DATA(result).
  5. Ative a classe global e execute-a como um app de console.

    1. Pressione Ctrl + F3 para ativar o objeto de desenvolvimento.

    2. Pressione F9 para executar a classe global como um aplicativo de console.