O Open SQL consiste em um conjunto de instruções ABAP que executam operações no banco de dados central no SAP Web AS ABAP. Os resultados das operações e as mensagens de erro são independentes do sistema de base de dados em uso. Open SQL proporciona assim uma sintaxe e a semântica uniforme para todos os sistemas de base de dados suportadas pela SAP. Programas ABAP que usam apenas instruções Open SQL iram funcionar em qualquer sistema SAP, independentemente do sistema de banco de dados em uso.
O Open SQL fornece uma solução moderna e inteligente para persistir dados nos sistemas SAP, no entanto Open SQL é baseado no paradigma de programação declarativa da linguagem SQL e utiliza os tipos de dados e os Data Objects que definem os tipos de campos do sistema SAP, além de também utilizar o dicionário de dados ABAP para manipular dados. Este modelo apesar de ser eficiente e rápido, se utilizado dentro das melhores praticas, não tratam os dados como objetos assim como os frameworks ORM mais modernos usados atualmente nas linguagens orientadas a objeto como o Hibernate, Rails , Entity Framework e vários outros.
A desvantagem é que o ABAP com o Open SQL não proporciona um modo simples a manipulação dos dados completamente orientados a objetos, não podemos manipular objetos e persisti-los do mesmo modo que os frameworks ORM nos proporcionam e nem utilizar recursos de identificadores automáticos que manipulam objetos do banco de dados como tipos de auto incrementos ou sequencias, mas podemos utilizar alguns Design Patterns para adaptar esta funcionalidade, o único inconveniente é que este tipo de programação pode gerar margem há uma mistura de paradigmas que pode ocasionar um código de baixa qualidade caso não utilizado conforme seus padrões. Por outro lado os sistemas SAP rodam em um ambiente pré estabelecido e já possuem todos os recursos necessários para que você possa manipular e persistir dados facilmente e você só sentirá falta dos recursos dos modernos dos frameworks ORM apenas se você já os utiliza em outras linguagens de programação.
ABAP: Open SQL
Obs: A SAP nos proporciona um framework de persistência ORM para trabalhar sobre o OpenSQL, veremos sobre estas classes mais adiante.
Persistence: Conceitos de Persistência
Persistindo Dados Com Web Dynpro e Open SQL
Os códigos a seguir utilizam os métodos da View de um modo simples para que seja de fácil entendimento, a manipulação de dados não estão escritos sob nenhum Design Pattern especifico além do MVC proporcionado pelo Web Dynpro.
1 – Crie uma nova tabela transparente chama ZPARTICIPANTE, crie seus tipos, utilize a figura abaixo para detalhes:
2 – Defina o tipo de tabela e a quantidade de registros previstos para a tabela:
3 – Quando finalizar ative sua tabela:
4 – O dicionário de dados e o Open SQL não nos proporcionam nenhum tipo de recurso para manipulação de IDs automáticos, ou objetos do banco de dados, já que não possuímos acesso diretamente a ele. No entanto utilizaremos um objeto chamado NUMBER RANGE.
Numer Range: Number Range Object Types
Entre na transação SNRO e crie um novo objeto chamado ZID_PAR:
5 – Em Number Length Domain use, NUM10 e em Warning % use o valor 5 ou o valor de porcentagem que deseja receber avisos quando a faixa estiver chegando ao seu limite. Salve.
6 – Clique em Intervals e crie um novo intervalo:
7 – Adicione a faixa de valores desejados que serão utilizados para criar seus identificadores:
8 – Crie um novo componente Web Dynpro para os dados da tabela, crie seus atributos no controlador e os use na View. Crie um evento para o botão e um método para gravar dos dados na tabela transparente:
9 – Ative seu componente Web Dynpro, e teste sua aplicação:
10 – Abra a transação SE16 para acessar o navegador de dados do Netweaver e verifique os dados gravados com sucesso:
Exemplo:
Neste exemplo criamos uma tabela transparente e persistimos dados no banco de dados corrente através do Open SQL.
ABAP
Método Botão – ONACTIONACAO_BOTAO_ENVIAR
method ONACTIONACAO_BOTAO_ENVIAR .
* // Retorna campos do contexto da View
DATA lo_nd_usuario_controler TYPE REF TO if_wd_context_node.
DATA lo_el_usuario_controler TYPE REF TO if_wd_context_element.
DATA ls_usuario_controler TYPE wd_this->Element_usuario_controler.
DATA lv_cargo TYPE wd_this->Element_usuario_controler-cargo.
* // Recupera node controller
lo_nd_usuario_controler = wd_context->get_child_node( name = wd_this->wdctx_usuario_controler ).
* // Recupera elemento via lead selection
lo_el_usuario_controler = lo_nd_usuario_controler->get_element( ).
* // Recupera atributo
lo_el_usuario_controler->get_attribute(
EXPORTING
name = `CARGO`
IMPORTING
value = lv_cargo ).
* // Define objetos Regex
DATA: regex TYPE REF TO cl_abap_regex,
matcher TYPE REF TO cl_abap_matcher.
* Cria objeto Regex e define Pattern
CREATE OBJECT regex
EXPORTING
pattern = '[a-zA-Z]+'.
* // Verifica valot do elemento contra o Pattern
matcher = regex->create_matcher( text = lv_cargo ).
* // Verifca Pattern
IF matcher->match( ) NE 'X'.
* // Define menssagem
data lo_api_controller type ref to if_wd_controller.
data lo_message_manager type ref to if_wd_message_manager.
lo_api_controller ?= wd_This->Wd_Get_Api( ).
* // Chama método de menssagem
CALL METHOD lo_api_controller->GET_MESSAGE_MANAGER
RECEIVING
MESSAGE_MANAGER = lo_message_manager.
* // Exibe mensagem
CALL METHOD lo_message_manager->REPORT_MESSAGE
EXPORTING
MESSAGE_TEXT = 'Cargo é exclusivamente um campo alphanumérico'
CANCEL_NAVIGATION = ABAP_TRUE.
ENDIF.
* // Gravar dados
wd_this->ONGRAVAR( ).
endmethod.
Método Gravação – ONGRAVAR
method ONGRAVAR .
* // Recupera dados do controlador
DATA lo_nd_usuario_controler TYPE REF TO if_wd_context_node.
DATA lo_el_usuario_controler TYPE REF TO if_wd_context_element.
DATA ls_usuario_controler TYPE wd_this->Element_usuario_controler.
DATA lv_usuario_login TYPE wd_this->Element_usuario_controler-usuario_login.
lo_nd_usuario_controler = wd_context->get_child_node( name = wd_this->wdctx_usuario_controler ).
lo_el_usuario_controler = lo_nd_usuario_controler->get_element( ).
* // Recupera Nome
lo_el_usuario_controler->get_attribute(
EXPORTING
name = `USUARIO_LOGIN`
IMPORTING
value = lv_usuario_login ).
* // Recupera Sobrenome
DATA lv_sobrenome TYPE wd_this->Element_usuario_controler-sobrenome.
lo_nd_usuario_controler = wd_context->get_child_node( name = wd_this->wdctx_usuario_controler ).
lo_el_usuario_controler = lo_nd_usuario_controler->get_element( ).
lo_el_usuario_controler->get_attribute(
EXPORTING
name = `SOBRENOME`
IMPORTING
value = lv_sobrenome ).
* // Recupera Cargo
DATA lv_cargo TYPE wd_this->Element_usuario_controler-cargo.
lo_nd_usuario_controler = wd_context->get_child_node( name = wd_this->wdctx_usuario_controler ).
lo_el_usuario_controler = lo_nd_usuario_controler->get_element( ).
lo_el_usuario_controler->get_attribute(
EXPORTING
name = `CARGO`
IMPORTING
value = lv_cargo ).
* // Recupera Salario
DATA lv_salario TYPE wd_this->Element_usuario_controler-salario.
lo_nd_usuario_controler = wd_context->get_child_node( name = wd_this->wdctx_usuario_controler ).
lo_el_usuario_controler = lo_nd_usuario_controler->get_element( ).
lo_el_usuario_controler->get_attribute(
EXPORTING
name = `SALARIO`
IMPORTING
value = lv_salario ).
* // Recupera Data
DATA lv_data TYPE wd_this->Element_usuario_controler-data.
lo_nd_usuario_controler = wd_context->get_child_node( name = wd_this->wdctx_usuario_controler ).
lo_el_usuario_controler = lo_nd_usuario_controler->get_element( ).
lo_el_usuario_controler->get_attribute(
EXPORTING
name = `DATA`
IMPORTING
value = lv_data ).
* // Recupera Genero
DATA lv_genero TYPE wd_this->Element_usuario_controler-genero.
lo_nd_usuario_controler = wd_context->get_child_node( name = wd_this->wdctx_usuario_controler ).
lo_el_usuario_controler = lo_nd_usuario_controler->get_element( ).
lo_el_usuario_controler->get_attribute(
EXPORTING
name = `GENERO`
IMPORTING
value = lv_genero ).
* // Recupera Ativo
DATA lv_ativo TYPE wd_this->Element_usuario_controler-ativo.
lo_nd_usuario_controler = wd_context->get_child_node( name = wd_this->wdctx_usuario_controler ).
lo_el_usuario_controler = lo_nd_usuario_controler->get_element( ).
lo_el_usuario_controler->get_attribute(
EXPORTING
name = `ATIVO`
IMPORTING
value = lv_ativo ).
* // Recupera Observacao
DATA lv_observacao TYPE wd_this->Element_usuario_controler-observacao.
lo_nd_usuario_controler = wd_context->get_child_node( name = wd_this->wdctx_usuario_controler ).
lo_el_usuario_controler = lo_nd_usuario_controler->get_element( ).
lo_el_usuario_controler->get_attribute(
EXPORTING
name = `OBSERVACAO`
IMPORTING
value = lv_observacao ).
* // Declara variáveis
DATA : nome TYPE ZNome,
sobrenome TYPE ZSobrenome,
cargo TYPE ZCargo,
salario TYPE Zsal,
data_adm TYPE Zdata,
genero TYPE ZGenero,
ativo TYPE Zativo,
observacao TYPE ZObservacao.
* // Alimenta dados.
nome = LV_USUARIO_LOGIN.
sobrenome = LV_SOBRENOME.
cargo = LV_CARGO.
salario = LV_SALARIO.
data_adm = LV_DATA.
genero = LV_GENERO.
ativo = LV_ATIVO.
observacao = LV_OBSERVACAO.
* // Recupera numero auto-incremento para o ID
DATA id_participante TYPE I.
CALL FUNCTION 'NUMBER_GET_NEXT'
EXPORTING
nr_range_nr = '1'
object = 'ZID_PAR'
IMPORTING
NUMBER = ID_PARTICIPANTE
EXCEPTIONS
INTERVAL_NOT_FOUND = 1
NUMBER_RANGE_NOT_INTERN = 2
OBJECT_NOT_FOUND = 3
QUANTITY_IS_0 = 4
QUANTITY_IS_NOT_1 = 5
INTERVAL_OVERFLOW = 6
BUFFER_OVERFLOW = 7
OTHERS = 8.
* // Cria Set de dados
DATA participante TYPE ZPARTICIPANTE.
PARTICIPANTE-ID_PART = ID_PARTICIPANTE.
PARTICIPANTE-NOME = NOME.
PARTICIPANTE-SOBRENOME = SOBRENOME.
PARTICIPANTE-CARGO = CARGO.
PARTICIPANTE-DATA = DATA_ADM.
PARTICIPANTE-GENERO = GENERO.
PARTICIPANTE-ATIVO = ATIVO.
PARTICIPANTE-OBSERVACAO = OBSERVACAO.
* // Insere dados na tabela
INSERT INTO ZPARTICIPANTE VALUES PARTICIPANTE.
IF SY-SUBRC = 0.
* Define menssagem
data lo_api_controller type ref to if_wd_controller.
data lo_message_manager type ref to if_wd_message_manager.
lo_api_controller ?= wd_This->Wd_Get_Api( ).
* Chama método de menssagem
CALL METHOD lo_api_controller->GET_MESSAGE_MANAGER
RECEIVING
MESSAGE_MANAGER = lo_message_manager.
* Exibe mensagem
CALL METHOD lo_message_manager->REPORT_SUCCESS
EXPORTING
MESSAGE_TEXT = 'Dados Inseridos com Sucesso'.
ENDIF.
endmethod.











