Migre aplicativos legados do Oracle Pro*C para o ECPG - Recomendações da AWS

As traduções são geradas por tradução automática. Em caso de conflito entre o conteúdo da tradução e da versão original em inglês, a versão em inglês prevalecerá.

Migre aplicativos legados do Oracle Pro*C para o ECPG

Criado por Sai Parthasaradhi (AWS) e Mahesh Balumuri (AWS)

Ambiente: PoC ou piloto

Origem: Oracle

Destino: PostgreSQL

Tipo R: redefinir arquitetura

Workload: Oracle

Tecnologias: migração; bancos de dados

Resumo

A maioria dos aplicativos legados que têm código SQL incorporado usa o pré-compilador do Oracle Pro*C para acessar o banco de dados. Ao migrar esses bancos de dados do Oracle para o Amazon Relational Database Service (Amazon RDS) para PostgreSQL ou Amazon Aurora Edição Compatível com PostgreSQL, você precisa converter o código do aplicativo em um formato compatível com o pré-compilador no PostgreSQL, chamado ECPG. Esse padrão descreve como converter o código do Oracle Pro*C em seu equivalente no PostgreSQL ECPG. 

Para obter mais informações sobre o Pro*C, consulte a documentação do Oracle. Para obter uma breve introdução ao ECPG, consulte a seção Informações adicionais.

Pré-requisitos e limitações

Pré-requisitos

  • Uma conta AWS ativa

  • Um banco de dados compatível com Amazon RDS para PostgreSQL ou Aurora compatível com PostgreSQL

  • Um banco de dados do Oracle em execução on-premises

Ferramentas

  • Os pacotes do PostgreSQL listados na seção seguinte.

  • AWS CLI: o AWS Command Line Interface (AWS CLI) é uma ferramenta de código aberto para interagir com serviços da AWS por meio de comandos em seu shell de linha de comando. Com configuração mínima, você pode executar comandos da AWS CLI que implementam funcionalidade equivalente àquela fornecida pelo Console de Gerenciamento da AWS baseado em navegador a partir de um prompt de comando.

Épicos

TarefaDescriçãoHabilidades necessárias
Instale pacotes do PostgreSQL.

Instale os pacotes PostgreSQL necessários usando os comandos a seguir.

yum update -y yum install -y yum-utils rpm -ivh https://download.postgresql.org/pub/repos/yum/reporpms/EL-8-x86_64/pgdg-redhat-repo-latest.noarch.rpm dnf -qy module disable postgresql
Desenvolvedor de aplicativos, DevOps engenheiro
Instale os arquivos de cabeçalho e as bibliotecas.

Instale o pacote postgresql12-devel, que contém arquivos de cabeçalho e bibliotecas, usando os comandos a seguir. Instale o pacote nos ambientes de desenvolvimento e de runtime para evitar erros no ambiente de execução.

dnf -y install postgresql12-devel yum install ncompress zip ghostscript jq unzip wget git -y

Somente para o ambiente de desenvolvimento, execute também os comandos a seguir.

yum install zlib-devel make -y ln -s /usr/pgsql-12/bin/ecpg /usr/bin/
Desenvolvedor de aplicativos, DevOps engenheiro
Configure a variável do caminho do ambiente.

Defina o caminho do ambiente para as bibliotecas de cliente do PostgreSQL.

export PATH=$PATH:/usr/pgsql-12/bin
Desenvolvedor de aplicativos, DevOps engenheiro
Instale software adicional conforme necessário.

Se necessário, instale o pgLoader como substituto do SQL*Loader no Oracle.

wget -O /etc/yum.repos.d/pgloader-ccl.repo https://dl.packager.io/srv/opf/pgloader-ccl/master/installer/el/7.repo yum install pgloader-ccl -y ln -s /opt/pgloader-ccl/bin/pgloader /usr/bin/

Se você estiver chamando qualquer aplicativo Java dos módulos Pro*C, instale o Java.

yum install java -y

Instale o ant para compilar o código Java.

yum install ant -y
Desenvolvedor de aplicativos, DevOps engenheiro
Instale a AWS CLI.

Instale a AWS CLI para executar comandos para interagir com os Serviços da AWS, como o AWS Secrets Manager e o Amazon Simple Storage Service (Amazon S3) a partir de seus aplicativos.

cd /tmp/ curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip" unzip awscliv2.zip ./aws/install -i /usr/local/aws-cli -b /usr/local/bin --update
Desenvolvedor de aplicativos, DevOps engenheiro
Identifique os programas a serem convertidos.

Identifique os aplicativos que você deseja converter do Pro*C para ECPG.

Desenvolvedor do aplicativo, proprietário do aplicativo
TarefaDescriçãoHabilidades necessárias
Remova os cabeçalhos indesejados.

Remova os cabeçalhos include que não são necessários no PostgreSQL, como oci.h, oratypes e sqlda.

Proprietário do aplicativo, desenvolvedor do aplicativo
Atualize as declarações de variáveis.

Adicione instruções EXEC SQL para todas as declarações de variáveis usadas como variáveis do host.

Remova as declarações EXEC SQL VAR, como as seguintes, do seu aplicativo.

EXEC SQL VAR query IS STRING(2048);
Desenvolvedor do aplicativo, proprietário do aplicativo
Atualize a funcionalidade ROWNUM.

A função ROWNUM não está disponível no PostgreSQL. Substitua isso pela função de janela ROW_NUMBER nas consultas SQL.

Código Pro*C:

SELECT SUBSTR(RTRIM(FILE_NAME,'.txt'),12) INTO :gcpclFileseq   FROM   (SELECT FILE_NAME FROM  DEMO_FILES_TABLE WHERE FILE_NAME    LIKE '%POC%' ORDER BY FILE_NAME DESC) FL2 WHERE ROWNUM <=1 ORDER BY ROWNUM;

Código ECPG:

SELECT SUBSTR(RTRIM(FILE_NAME,'.txt'),12) INTO :gcpclFileseq   FROM   (SELECT FILE_NAME , ROW_NUMBER() OVER (ORDER BY FILE_NAME DESC) AS ROWNUM FROM  demo_schema.DEMO_FILES_TABLE WHERE FILE_NAME    LIKE '%POC%' ORDER BY FILE_NAME DESC) FL2 WHERE ROWNUM <=1 ORDER BY ROWNUM;
Desenvolvedor do aplicativo, proprietário do aplicativo
Atualize os parâmetros da função para usar variáveis de alias.

No PostgreSQL, os parâmetros da função não podem ser usados como variáveis do host. Substitua-os usando uma variável de alias.

Código Pro*C:

int processData(int referenceId){   EXEC SQL char col_val[100];   EXEC SQL select column_name INTO :col_val from table_name where col=:referenceId; }

Código ECPG:

int processData(int referenceIdParam){   EXEC SQL int referenceId = referenceIdParam;   EXEC SQL char col_val[100];   EXEC SQL select column_name INTO :col_val from table_name where col=:referenceId; }
Desenvolvedor do aplicativo, proprietário do aplicativo
Atualize os tipos de estrutura.

Defina os tipos struct em EXEC SQL BEGIN e blocos END com typedef se as variáveis ​​de tipo struct forem usadas como variáveis ​​de host. Se os tipos struct forem definidos em arquivos header (.h), inclua os arquivos com instruções include (incluir) EXEC SQL.

Código Pro*C:

Arquivo de cabeçalho (demo.h)

struct s_partition_ranges {  char   sc_table_group[31];  char   sc_table_name[31];  char   sc_range_value[10]; }; struct s_partition_ranges_ind {   short    ss_table_group;   short    ss_table_name;   short    ss_range_value; };

Código ECPG:

Arquivo de cabeçalho (demo.h)

EXEC SQL BEGIN DECLARE SECTION; typedef struct {   char   sc_table_group[31];   char   sc_table_name[31];   char   sc_range_value[10]; } s_partition_ranges; typedef struct {   short    ss_table_group;   short    ss_table_name;   short    ss_range_value; } s_partition_ranges_ind; EXEC SQL END DECLARE SECTION;

Arquivo Pro*C (demo.pc)

#include "demo.h" struct s_partition_ranges gc_partition_data[MAX_PART_TABLE] ; struct s_partition_ranges_ind gc_partition_data_ind[MAX_PART_TABLE] ;

Arquivo ECPG (demo.pc)

exec sql include "demo.h" EXEC SQL BEGIN DECLARE SECTION; s_partition_ranges gc_partition_data[MAX_PART_TABLE] ; s_partition_ranges_ind gc_partition_data_ind[MAX_PART_TABLE] ; EXEC SQL END DECLARE SECTION;
Desenvolvedor do aplicativo, proprietário do aplicativo
Modifique a lógica para fazer buscas nos cursores.

Para buscar várias linhas nos cursores usando variáveis de matriz, altere o código a ser usado FETCH FORWARD.

Código Pro*C:

EXEC SQL char  aPoeFiles[MAX_FILES][FILENAME_LENGTH]; EXEC SQL FETCH filename_cursor into :aPoeFiles;

Código ECPG:

EXEC SQL char  aPoeFiles[MAX_FILES][FILENAME_LENGTH]; EXEC SQL int fetchSize = MAX_FILES; EXEC SQL FETCH FORWARD :fetchSize filename_cursor into :aPoeFiles;
Desenvolvedor do aplicativo, proprietário do aplicativo
Modifique as chamadas de pacotes que não têm valores de retorno.

As funções do pacote Oracle que não têm valores de retorno devem ser chamadas com uma variável indicadora. Se seu aplicativo incluir várias funções com o mesmo nome ou se as funções de tipo desconhecido gerarem erros de runtime, converta os valores para os tipos de dados.

Código Pro*C:

void ProcessData (char *data , int id) {                EXEC SQL EXECUTE                BEGIN                   pkg_demo.process_data (:data, :id);                                                                                                  END;        END-EXEC; }

Código ECPG:

void ProcessData (char *dataParam, int idParam ) {         EXEC SQL char *data = dataParam;         EXEC SQL int id = idParam;         EXEC SQL short rowInd;         EXEC SQL short rowInd = 0;         EXEC SQL SELECT pkg_demo.process_data (                        inp_data => :data::text,                        inp_id => :id                ) INTO :rowInd; }
Desenvolvedor do aplicativo, proprietário do aplicativo
Reescreva as variáveis SQL_CURSOR.

Reescreva a variável SQL_CURSOR e sua implementação.

Código Pro*C:

/* SQL Cursor */ SQL_CURSOR      demo_cursor; EXEC SQL ALLOCATE :demo_cursor; EXEC SQL EXECUTE   BEGIN       pkg_demo.get_cursor(             demo_cur=>:demo_cursor       );   END; END-EXEC;

Código ECPG:

EXEC SQL DECLARE demo_cursor CURSOR FOR SELECT          * from     pkg_demo.open_filename_rc(             demo_cur=>refcursor           ) ; EXEC SQL char open_filename_rcInd[100]; # As the below function returns cursor_name as # return we need to use char[] type as indicator. EXEC SQL SELECT pkg_demo.get_cursor (         demo_cur=>'demo_cursor'     ) INTO :open_filename_rcInd;
Desenvolvedor do aplicativo, proprietário do aplicativo
Aplique padrões comuns de migração.
  • Altere as consultas SQL para que sejam compatíveis com o PostgreSQL.

  • Mova blocos anônimos para o banco de dados quando não houver suporte no ECPG.

  • Remova a lógica dbms_application_info, que não é compatível com o PostgreSQL.

  • Mova as instruções EXEC SQL COMMIT após o fechamento do cursor. Se você confirmar consultas enquanto estiver no loop para buscar os registros do cursor, o cursor será fechado e um erro de cursor não existe será exibido.

  • Para obter informações sobre como lidar com exceções no ECPG e códigos de erro, consulte Tratamento de erros na documentação do PostgreSQL.

Desenvolvedor do aplicativo, proprietário do aplicativo
Ative a depuração, se necessário.

Para executar o programa ECPG no modo de depuração, adicione o seguinte comando dentro do bloco de funções principal.

ECPGdebug(1, stderr);
Desenvolvedor do aplicativo, proprietário do aplicativo
TarefaDescriçãoHabilidades necessárias
Crie um arquivo executável para o ECPG.

Se você tiver um arquivo de origem SQL C incorporado chamado prog1.pgc, poderá criar um programa executável usando a seguinte sequência de comandos.

ecpg prog1.pgc cc -I/usr/local/pgsql/include -c prog1.c cc -o prog1 prog1.o -L/usr/local/pgsql/lib -lecpg
Desenvolvedor do aplicativo, proprietário do aplicativo
Crie um arquivo make para compilação.

Criar um arquivo make para compilar o programa ECPG, conforme mostrado no arquivo de exemplo a seguir.

CFLAGS ::= $(CFLAGS) -I/usr/pgsql-12/include -g -Wall LDFLAGS ::= $(LDFLAGS) -L/usr/pgsql-12/lib -Wl,-rpath,/usr/pgsql-12/lib LDLIBS ::= $(LDLIBS) -lecpg PROGRAMS = test  .PHONY: all clean %.c: %.pgc   ecpg $< all: $(PROGRAMS) clean:     rm -f $(PROGRAMS) $(PROGRAMS:%=%.c) $(PROGRAMS:%=%.o)
Desenvolvedor do aplicativo, proprietário do aplicativo
TarefaDescriçãoHabilidades necessárias
Teste o código.

Teste o código do aplicativo convertido para verificar se ele funciona corretamente.

Desenvolvedor de aplicativos, proprietário do aplicativo, engenheiro de teste

Recursos relacionados

Mais informações

O PostgreSQL tem um pré-compilador SQL incorporado, o ECPG, que é equivalente ao pré-compilador do Oracle Pro*C. O ECPG converte programas C que têm instruções SQL incorporadas em código C padrão, substituindo as chamadas SQL por chamadas de funções especiais. Os arquivos de saída podem então ser processados com qualquer cadeia de ferramentas do compilador C.

Arquivos de entrada e saída

O ECPG converte cada arquivo de entrada especificado na linha de comando no arquivo de saída C correspondente. Se um nome de arquivo de entrada não tiver uma extensão de arquivo, será assumido o formato .pgc. A extensão do arquivo é substituída por .c para estruturar o nome do arquivo de saída. No entanto, você pode substituir o nome padrão do arquivo de saída usando a opção -o.

Se você usar um traço (-) como nome do arquivo de entrada, o ECPG lerá o programa da entrada padrão e gravará na saída padrão, a menos que você substitua isso usando a opção -o.

Arquivos de cabeçalho

Quando o compilador do PostgreSQL compila os arquivos de código C pré-processados, ele procura os arquivos de cabeçalho ECPG no diretório include do PostgreSQL. Portanto, talvez seja necessário usar a opção -I de apontar o compilador para o diretório correto (por exemplo,-I/usr/local/pgsql/include).

Bibliotecas

Os programas que usam código C com SQL incorporado precisam ser vinculados à biblioteca libecpg. Por exemplo, você pode usar as opções  -L/usr/local/pgsql/lib -lecpg do vinculador.

Os aplicativos ECPG convertidos chamam funções na biblioteca libpq por meio da biblioteca SQL incorporada (ecpglib) e se comunicam com o servidor do PostgreSQL usando o protocolo padrão de frontend/backend.