Files
wiki/SAP/EXPORT_IMPORT_ABAP_table.md

637 lines
17 KiB
Markdown

---
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)