diff --git a/SAP/EXPORT_IMPORT_ABAP_table.md b/SAP/EXPORT_IMPORT_ABAP_table.md new file mode 100644 index 0000000..470d335 --- /dev/null +++ b/SAP/EXPORT_IMPORT_ABAP_table.md @@ -0,0 +1,636 @@ +--- +title: EXPORT IMPORT em ABAP +description: Teoria, exemplos e persistência em banco com TO/FROM DATABASE +published: true +date: 2026-08-12T12:10:37.961Z +tags: +editor: markdown +dateCreated: 2026-08-12T12:10:37.961Z +--- + +# EXPORT e IMPORT em ABAP + +## Teoria, exemplos e persistência em banco com `TO/FROM DATABASE` + +## 1. Visão geral + +Em ABAP, as instruções `EXPORT` e `IMPORT` permitem salvar e recuperar um conjunto de objetos ABAP como um **data cluster**. + +Um data cluster é uma representação serializada de variáveis, estruturas ou tabelas internas. O SAP grava os dados em um formato técnico e, no momento do `IMPORT`, reconstrói os objetos ABAP originais. + +Exemplo conceitual: + +```text +Tabela interna ABAP + | + | EXPORT + v +Dados serializados (data cluster) + | + | IMPORT + v +Tabela interna ABAP novamente +``` + +O mesmo mecanismo pode utilizar diferentes meios de armazenamento: + +| Meio | Sintaxe | Uso principal | +|---|---|---| +| Memória ABAP | `TO/FROM MEMORY` | Compartilhar dados entre programas na mesma sessão interna | +| Banco de dados | `TO/FROM DATABASE` | Persistir dados em uma tabela de export/import, como `INDX` | +| Buffer compartilhado | `TO/FROM SHARED BUFFER` | Compartilhar dados pelo buffer do servidor de aplicação | +| Buffer binário | `TO/FROM DATA BUFFER` | Serializar dados em uma variável `XSTRING` | +| Arquivo | `TO/FROM DATASET` | Variante antiga para arquivos; normalmente prefere-se `OPEN DATASET` | + +Este documento concentra-se em `TO/FROM DATABASE`, especialmente no uso da tabela `INDX`. + +--- + +## 2. O que significa `TO/FROM DATABASE` + +Quando se usa: + +```abap +EXPORT ... TO DATABASE indx(z1) ID 'CHAVE_001'. +``` + +o ABAP não grava as colunas da estrutura diretamente como colunas de negócio. Ele serializa as variáveis e grava o resultado em uma tabela de export/import. + +A leitura é feita assim: + +```abap +IMPORT ... FROM DATABASE indx(z1) ID 'CHAVE_001'. +``` + +O sistema localiza o cluster usando a tabela, a área e o identificador. Depois, desserializa o conteúdo e preenche as variáveis informadas no `IMPORT`. + +### 2.1 Estrutura da sintaxe + +```abap +EXPORT objeto_1 = variavel_1 + objeto_2 = variavel_2 + TO DATABASE tabela_export_import(area) + ID identificador. +``` + +```abap +IMPORT objeto_1 = variavel_1 + objeto_2 = variavel_2 + FROM DATABASE tabela_export_import(area) + ID identificador. +``` + +Os elementos principais são: + +| Elemento | Descrição | +|---|---| +| `tabela_export_import` | Tabela de banco compatível com armazenamento de clusters, normalmente `INDX` ou uma tabela `Z` apropriada | +| `area` | Área de dois caracteres, também conhecida como `RELID`; funciona como uma categoria de armazenamento | +| `ID` | Chave lógica do cluster; identifica o conjunto de dados salvo | +| `objeto_1` | Nome lógico usado dentro do cluster | +| `variavel_1` | Variável ABAP cujo conteúdo será gravado ou preenchido | + +O nome lógico e a variável podem ter nomes diferentes: + +```abap +EXPORT dados_materiais = lt_mara + TO DATABASE indx(z1) + ID 'MARA_001'. +``` + +Na leitura: + +```abap +IMPORT dados_materiais = lt_mara + FROM DATABASE indx(z1) + ID 'MARA_001'. +``` + +--- + +## 3. A tabela `INDX` + +`INDX` é uma tabela técnica utilizada pelo SAP para armazenar dados exportados/importados. Ela não possui, normalmente, colunas de negócio como `MATNR`, `WERKS` ou `MENGE`. + +O conteúdo do cluster é armazenado de forma serializada em campos técnicos. Dependendo da versão do SAP e do banco de dados, podem aparecer campos como: + +- `MANDT`: cliente SAP; +- `RELID`: área do cluster; +- `SRTFD`, `SRTF2` e outros campos técnicos de chave; +- `CLUSTR` e/ou `CLUSTD`: conteúdo serializado do cluster. + +Por isso, um `SELECT` direto na `INDX` não devolve a tabela interna original em formato legível: + +```abap +SELECT * FROM indx INTO TABLE @DATA(lt_indx). +``` + +Esse `SELECT` retorna os registros técnicos e o conteúdo serializado. Para reconstruir os objetos, deve-se usar `IMPORT`. + +> Não se deve tentar interpretar ou alterar manualmente os campos serializados do cluster por SQL. A leitura deve ser feita com `IMPORT`, usando a mesma tabela, área e chave utilizadas no `EXPORT`. + +--- + +## 4. Exemplo completo: exportar uma tabela interna para `INDX` + +O exemplo abaixo seleciona materiais, grava a tabela interna em `INDX` e depois a recupera. + +### 4.1 Programa de gravação + +```abap +REPORT z_export_mara_indx. + +DATA lt_mara TYPE STANDARD TABLE OF mara. + +SELECT * + FROM mara + INTO TABLE @lt_mara + UP TO 100 ROWS. + +IF sy-subrc <> 0. + MESSAGE 'Nenhum material encontrado' TYPE 'I'. + RETURN. +ENDIF. + +EXPORT dados_materiais = lt_mara + TO DATABASE indx(z1) + ID 'MARA_001'. + +IF sy-subrc = 0. + COMMIT WORK AND WAIT. + MESSAGE 'Cluster gravado com sucesso' TYPE 'S'. +ELSE. + ROLLBACK WORK. + MESSAGE 'Erro ao gravar o cluster' TYPE 'E'. +ENDIF. +``` + +### 4.2 Programa de leitura + +```abap +REPORT z_import_mara_indx. + +DATA lt_mara TYPE STANDARD TABLE OF mara. + +IMPORT dados_materiais = lt_mara + FROM DATABASE indx(z1) + ID 'MARA_001'. + +IF sy-subrc <> 0. + MESSAGE 'Cluster não encontrado ou inválido' TYPE 'I'. + RETURN. +ENDIF. + +LOOP AT lt_mara INTO DATA(ls_mara). + WRITE: / ls_mara-matnr, + ls_mara-mtart, + ls_mara-mbrsh. +ENDLOOP. +``` + +### 4.3 O que acontece nesse fluxo + +1. `lt_mara` é preenchida com dados da tabela `MARA`. +2. `EXPORT` serializa a tabela interna. +3. O cluster é identificado pela combinação da tabela, área `Z1` e ID `MARA_001`. +4. O banco recebe o registro técnico na `INDX`. +5. `COMMIT WORK` confirma a alteração da unidade lógica de trabalho. +6. O segundo programa executa `IMPORT` usando a mesma identificação. +7. O conteúdo é reconstruído em `lt_mara`. + +--- + +## 5. Exportar várias variáveis no mesmo cluster + +É possível armazenar uma tabela interna, uma estrutura e variáveis simples no mesmo cluster. + +```abap +DATA: lt_mara TYPE STANDARD TABLE OF mara, + lv_datum TYPE sydatum, + lv_user TYPE syuname, + lv_total TYPE i. + +lv_datum = sy-datum. +lv_user = sy-uname. +lv_total = lines( lt_mara ). + +EXPORT dados_materiais = lt_mara + data_execucao = lv_datum + usuario = lv_user + quantidade = lv_total + TO DATABASE indx(z1) + ID 'MARA_001'. + +COMMIT WORK AND WAIT. +``` + +A recuperação precisa solicitar os mesmos nomes lógicos: + +```abap +IMPORT dados_materiais = lt_mara + data_execucao = lv_datum + usuario = lv_user + quantidade = lv_total + FROM DATABASE indx(z1) + ID 'MARA_001'. +``` + +Se o programa importar somente alguns objetos, os demais não serão preenchidos. Por exemplo: + +```abap +IMPORT dados_materiais = lt_mara + FROM DATABASE indx(z1) + ID 'MARA_001'. +``` + +Nesse caso, apenas `lt_mara` será recuperada. + +--- + +## 6. Como escolher a área e o ID + +A área e o ID formam parte da identificação do cluster. + +```abap +EXPORT dados = lt_data + TO DATABASE indx(z1) + ID 'PEDIDO_000001'. +``` + +Uma estratégia simples é: + +| Campo | Exemplo | Finalidade | +|---|---|---| +| Área | `Z1` | Separar a finalidade ou aplicação | +| ID | `PEDIDO_000001` | Identificar o registro lógico | + +Exemplos de IDs: + +```abap +ID 'ZRELATORIO_20260811'. +ID 'PEDIDO_000001'. +ID lv_id. +``` + +Boas práticas: + +- usar uma área reservada para o desenvolvimento, como `Z1` ou `Z2`; +- usar um prefixo da aplicação, como `ZFI_`, `ZMM_` ou `ZPP_`; +- garantir que o ID seja único para o conjunto de dados; +- documentar o formato do ID; +- não reutilizar o mesmo ID para estruturas incompatíveis; +- considerar o cliente SAP (`MANDT`) quando o desenho da aplicação depender de dados separados por cliente. + +Se o mesmo ID for exportado novamente, o conteúdo anterior será substituído na mesma identificação lógica. + +--- + +## 7. Verificar se o cluster existe + +A forma mais simples é testar `sy-subrc` após o `IMPORT`: + +```abap +IMPORT dados = lt_data + FROM DATABASE indx(z1) + ID 'PEDIDO_000001'. + +CASE sy-subrc. + WHEN 0. + WRITE: / 'Cluster importado com sucesso'. + WHEN OTHERS. + WRITE: / 'Cluster não encontrado ou não compatível'. +ENDCASE. +``` + +Em código de produção, também é recomendável: + +- limpar as variáveis antes do `IMPORT`; +- validar se a tabela interna foi preenchida; +- tratar a ausência do cluster; +- garantir compatibilidade entre a estrutura usada no `EXPORT` e no `IMPORT`. + +Exemplo: + +```abap +CLEAR lt_data. + +IMPORT dados = lt_data + FROM DATABASE indx(z1) + ID lv_id. + +IF sy-subrc <> 0 OR lt_data IS INITIAL. + "Tratar cluster ausente ou sem dados + RETURN. +ENDIF. +``` + +--- + +## 8. Excluir dados gravados + +Para remover um cluster específico: + +```abap +DELETE FROM DATABASE indx(z1) + ID 'MARA_001'. + +IF sy-subrc = 0. + COMMIT WORK AND WAIT. +ENDIF. +``` + +A exclusão deve utilizar a mesma tabela, área e identificação do `EXPORT`. + +Não se deve usar um `DELETE` SQL genérico na `INDX` sem conhecer exatamente a chave técnica e as regras da aplicação. O comando ABAP específico é mais seguro para excluir o cluster lógico. + +--- + +## 9. Consultar o conteúdo lógico com `IMPORT DIRECTORY` + +Quando não se conhece quais objetos foram armazenados, pode-se consultar o diretório do cluster. + +```abap +DATA lt_directory TYPE STANDARD TABLE OF cdir. + +IMPORT DIRECTORY INTO lt_directory + FROM DATABASE indx(z1) + ID 'MARA_001'. + +LOOP AT lt_directory INTO DATA(ls_directory). + WRITE: / ls_directory-name. +ENDLOOP. +``` + +O diretório informa os objetos armazenados, mas não substitui o `IMPORT` dos valores. Para recuperar os dados, é necessário conhecer os nomes e os tipos esperados. + +--- + +## 10. Compatibilidade entre `EXPORT` e `IMPORT` + +O programa que importa precisa conhecer os tipos dos dados exportados. + +Exemplo correto: + +```abap +TYPES tt_data TYPE STANDARD TABLE OF mara WITH EMPTY KEY. + +DATA lt_data TYPE tt_data. + +IMPORT dados = lt_data + FROM DATABASE indx(z1) + ID 'MARA_001'. +``` + +Cuidados importantes: + +- não alterar a estrutura sem planejar compatibilidade; +- evitar importar um cluster antigo para uma estrutura completamente diferente; +- versionar o conteúdo quando a estrutura puder mudar; +- usar um campo de versão dentro do cluster. + +Exemplo com versão: + +```abap +DATA: lv_versao TYPE i VALUE 1, + lt_data TYPE STANDARD TABLE OF mara. + +EXPORT versao = lv_versao + dados = lt_data + TO DATABASE indx(z1) + ID 'MARA_001'. +``` + +Na leitura: + +```abap +DATA: lv_versao TYPE i, + lt_data TYPE STANDARD TABLE OF mara. + +IMPORT versao = lv_versao + dados = lt_data + FROM DATABASE indx(z1) + ID 'MARA_001'. + +IF sy-subrc = 0 AND lv_versao = 1. + "Processar versão conhecida +ELSE. + "Tratar versão incompatível +ENDIF. +``` + +--- + +## 11. `COMMIT WORK` e unidade lógica de trabalho + +O `EXPORT TO DATABASE` participa da unidade lógica de trabalho do programa. Em um fluxo que precisa garantir a persistência, confirme a alteração: + +```abap +EXPORT dados = lt_data + TO DATABASE indx(z1) + ID lv_id. + +IF sy-subrc = 0. + COMMIT WORK AND WAIT. +ELSE. + ROLLBACK WORK. +ENDIF. +``` + +Em uma aplicação real, o momento do `COMMIT WORK` deve respeitar o controle transacional do processo. Evite executar `COMMIT WORK` dentro de uma classe ou função que não seja responsável pela transação inteira, pois isso pode confirmar outras alterações pendentes. + +--- + +## 12. Controle de concorrência + +Dois processos podem tentar gravar o mesmo ID ao mesmo tempo. Para evitar sobrescrita ou inconsistência: + +- defina IDs realmente únicos; +- use bloqueios lógicos quando houver atualização concorrente; +- não permita que dois processos reutilizem o mesmo ID sem coordenação; +- grave também usuário, data e versão quando for necessário rastreamento. + +O cluster não substitui uma tabela de negócio com chave, histórico, índices e controle de atualização. + +--- + +## 13. Tabela `INDX` não é uma tabela de negócio + +A `INDX` deve ser tratada como armazenamento técnico de objetos serializados. Ela não é adequada para: + +- consultas SQL por campos internos do objeto; +- joins com tabelas de negócio; +- relatórios analíticos; +- filtros por campos como material, centro ou fornecedor; +- atualização parcial de uma coluna; +- integração externa que espera dados relacionais. + +Se for necessário consultar `MATNR`, `WERKS` ou outro campo diretamente no banco, o melhor desenho é uma tabela transparente com colunas próprias. + +--- + +## 14. Diferença entre `INDX` e uma tabela Cluster do DDIC + +Os termos são parecidos, mas representam situações diferentes: + +### `EXPORT TO DATABASE INDX(...)` + +Grava um data cluster ABAP serializado em uma tabela de export/import, como `INDX`. + +### Tabela Cluster do Dicionário ABAP + +É um tipo antigo de tabela DDIC em que várias tabelas lógicas podiam ser armazenadas de forma agrupada em uma tabela física. + +Portanto, usar `EXPORT TO DATABASE` não significa exportar diretamente uma tabela de negócio cluster. Significa armazenar um conjunto de variáveis ABAP serializadas. + +--- + +## 15. Quando usar e quando não usar + +### Pode fazer sentido usar quando: + +- é necessário guardar temporariamente um conjunto de dados ABAP; +- um processo posterior, controlado pela mesma aplicação, fará o `IMPORT`; +- os dados não precisam ser consultados por SQL; +- a estrutura dos dados é conhecida pelo programa consumidor; +- há necessidade de preservar uma tabela interna entre etapas de processamento. + +### Deve ser evitado quando: + +- os dados são mestres ou transacionais; +- outros sistemas precisam consumir os dados; +- é necessário consultar ou filtrar os campos no banco; +- é necessário fazer join ou criar relatórios; +- a estrutura muda frequentemente; +- o volume é grande e precisa de controle de retenção; +- uma tabela transparente ou uma solução de persistência orientada a objetos atende melhor. + +Para novos desenvolvimentos, normalmente são preferíveis tabelas transparentes `Z`, classes de persistência e formatos de integração como JSON, XML ou APIs. + +--- + +## 16. Exemplo de classe utilitária + +Um uso mais organizado é encapsular o acesso em uma classe. + +```abap +CLASS zcl_cluster_storage DEFINITION + PUBLIC FINAL CREATE PUBLIC. + + PUBLIC SECTION. + CLASS-METHODS save + IMPORTING + iv_id TYPE char30 + it_data TYPE STANDARD TABLE. + + CLASS-METHODS load + IMPORTING + iv_id TYPE char30 + EXPORTING + et_data TYPE STANDARD TABLE. +ENDCLASS. +``` + +O exemplo acima é apenas ilustrativo: em ABAP, para garantir tipagem forte, normalmente deve-se definir um tipo de tabela específico, em vez de usar `STANDARD TABLE` genérico. + +Uma implementação tipada seria mais segura: + +```abap +CLASS zcl_mara_cluster DEFINITION + PUBLIC FINAL CREATE PUBLIC. + + PUBLIC SECTION. + TYPES tt_mara TYPE STANDARD TABLE OF mara WITH EMPTY KEY. + + CLASS-METHODS save + IMPORTING + iv_id TYPE char30 + it_mara TYPE tt_mara. + + CLASS-METHODS load + IMPORTING + iv_id TYPE char30 + RETURNING + VALUE(rt_mara) TYPE tt_mara. +ENDCLASS. +``` + +Implementação: + +```abap +CLASS zcl_mara_cluster IMPLEMENTATION. + + METHOD save. + EXPORT dados = it_mara + TO DATABASE indx(z1) + ID iv_id. + + IF sy-subrc <> 0. + RAISE EXCEPTION TYPE cx_sy_import_mismatch_error. + ENDIF. + ENDMETHOD. + + METHOD load. + IMPORT dados = rt_mara + FROM DATABASE indx(z1) + ID iv_id. + ENDMETHOD. + +ENDCLASS. +``` + +Em um desenvolvimento real, é melhor definir exceções próprias e tratar explicitamente ausência, incompatibilidade e falha de persistência. + +--- + +## 17. Checklist de implementação + +Antes de usar `EXPORT TO DATABASE`, verifique: + +- [ ] A tabela utilizada é compatível com export/import? +- [ ] A área possui dois caracteres e está documentada? +- [ ] O ID é único e possui uma regra clara? +- [ ] O mesmo nome lógico será usado no `IMPORT`? +- [ ] Os tipos do `EXPORT` e do `IMPORT` são compatíveis? +- [ ] O processo controla `sy-subrc`? +- [ ] O `COMMIT WORK` está no ponto correto da transação? +- [ ] Existe tratamento para dados antigos ou estrutura versionada? +- [ ] Há controle contra concorrência e sobrescrita? +- [ ] A solução realmente precisa de cluster ou uma tabela transparente seria melhor? +- [ ] Existe rotina de limpeza para evitar acúmulo de registros? + +## 18. Resumo final + +O padrão básico é: + +```abap +EXPORT dados = lt_data + TO DATABASE indx(z1) + ID 'CHAVE_001'. + +COMMIT WORK AND WAIT. +``` + +Depois: + +```abap +IMPORT dados = lt_data + FROM DATABASE indx(z1) + ID 'CHAVE_001'. +``` + +Para excluir: + +```abap +DELETE FROM DATABASE indx(z1) + ID 'CHAVE_001'. + +COMMIT WORK AND WAIT. +``` + +A principal ideia é: `EXPORT TO DATABASE` persiste um **cluster serializado**, e `IMPORT FROM DATABASE` reconstrói os objetos ABAP. A `INDX` é um armazenamento técnico; ela não deve ser tratada como uma tabela relacional de negócio. + +### Referências + +- [SAP Help — Data Clusters](https://help.sap.com/docs/ABAP_PLATFORM_NEW/7bfe8cdcfbb040dcb6702dada8c3e2f0/2bd6a428f3fd421eb60272c3abe6463f.html) +- [ABAP Keyword Documentation — IMPORT](https://eduardocopat.github.io/abap-docs/7.54/abapimport_medium/) +- [SAP Help — Pooled and Cluster Tables](https://help.sap.com/docs/SAP_NETWEAVER_AS_ABAP_FOR_SOH_740/ec1c9c8191b74de98feb94001a95dd76/cf21f083446011d189700000e8322d00.html)