Executar Select no MySQL via Progress 4GL

Neste post teremos um exemplo de como realizar conexão ao banco de dados MySQL em tempo de execução do OpenEdge Progress e executar comandos de SELEC importando os dados obtidos para uma tabela temporária.

Para conhecimento a base deste conteúdo está disponível no  Knowledge: https://knowledgebase.progress.com/articles/Knowledge/21356

A ultima versão do conector ODBC fica disponível neste endereço: https://dev.mysql.com/downloads/connector/odbc/

Antes de executar o script é preciso criar uma fonte de dados no Windows onde o programa vai ser executado:

Deve obter sucesso ao realizar o teste de conexão.

Neste exemplo foi criado o banco de dados DatabaseTeste e nele apenas 3 tabelas, Pais, Estado e Cidades

Esquema do banco de dados no MySQL

Caso queira o SQL pronto para gerar essas 3 tabelas e o conteúdo delas, ou seja, o pais que no caso é o Brasil, os estados e cidades, pode ser obtido pelo post de João Oliveira no site zerobugs neste endereço: https://zerobugs.com.br/ver-post/codigo-sql-com-todas-as-cidades-e-estados-do-brasil-62/

/* Objetos para conexao com MySQL  */
DEFINE VARIABLE ObjRecordSet AS COM-HANDLE NO-UNDO.
DEFINE VARIABLE ObjConnection AS COM-HANDLE NO-UNDO.
DEFINE VARIABLE ObjCommand AS COM-HANDLE NO-UNDO.

/* Parametros para conexao e extrassao de dados */
DEFINE VARIABLE ODBC-DSN AS CHARACTER NO-UNDO.
DEFINE VARIABLE ODBC-SERVER AS CHARACTER NO-UNDO.
DEFINE VARIABLE ODBC-DATABASE AS CHARACTER NO-UNDO.
DEFINE VARIABLE ODBC-PORT AS CHARACTER NO-UNDO.
DEFINE VARIABLE ODBC-USERID AS CHARACTER NO-UNDO.
DEFINE VARIABLE ODBC-PASSWD AS CHARACTER NO-UNDO.
DEFINE VARIABLE ODBC-QUERY AS CHARACTER NO-UNDO.
DEFINE VARIABLE ODBC-STATUS AS CHARACTER NO-UNDO.
DEFINE VARIABLE ODBC-RECCOUNT AS INTEGER NO-UNDO.
DEFINE VARIABLE ODBC-NULL AS CHARACTER NO-UNDO.
DEFINE VARIABLE ODBC-CURSOR AS INTEGER NO-UNDO.

define temp-table ttPais
    field id as intege
    field nome as character
    field sigla as character.

define temp-table ttEstado
    field id as integer
    field nome as character
    field uf as character
    field idPais as integer.

define temp-table ttCidade
    field id as integer
    field nome as character
    field idEstado as integer.

/* Cria o objeto para conexao com MySQL */
CREATE "ADODB.Connection" ObjConnection.
/* Cria objeto Record para armazenar os dados retornados da consulta */
CREATE "ADODB.RecordSet" ObjRecordSet.
/* Cria objeto para envio do comando SQL */
CREATE "ADODB.Command" ObjCommand.
 
/* Parametros para conexao */
ASSIGN
    ODBC-DSN = "Nome do Data source"
    ODBC-SERVER = "IP servidor"
    ODBC-DATABASE = "Banco de dados"
    ODBC-PORT = "Porta"
    ODBC-USERID = "Usuario"
    ODBC-PASSWD = "Senha".

/* Abre conexão ODBC */
ObjConnection:OPEN("DATA SOURCE=" + ODBC-DSN + 
                   ";SERVER=" + ODBC-SERVER +
                   ";PORT=" + ODBC-PORT +
                   ";DATABASE=" + ODBC-DATABASE,
                   ODBC-USERID,
                   ODBC-PASSWD, 0) no-error.

/* Verifica se houve erro de conexao */
IF ( ERROR-STATUS:NUM-MESSAGES > 0 ) THEN
    ODBC-STATUS = "Erro: Nao foi possivel estabelecer conexao.".
ELSE DO:
    /* Configura os objetos */
    ASSIGN
        ObjCommand:ActiveConnection = ObjConnection
        ObjCommand:CommandType = 1 /* adCmdText */
        ObjConnection:CursorLocation = 3 /* adUseClient */
        ObjRecordSet:CursorType = 3 /* adOpenStatic */
        ObjRecordSet:LockType = 3.

    /* Processo para carregar Paises */
    assign ObjCommand:CommandText = "SELECT * FROM pais;".

    assign ObjRecordSet = ObjCommand:EXECUTE(,,) no-error.
    
    assign ODBC-RECCOUNT = ObjRecordSet:RecordCount.

    /* Se retornou registro */
    IF ODBC-RECCOUNT > 0
    AND ODBC-RECCOUNT <> ? then DO:
        ObjRecordSet:MoveFirst NO-ERROR.

        DO WHILE ODBC-CURSOR < ODBC-RECCOUNT:
            create ttPais.
            assign
                ttPais.id = integer(ObjRecordSet:fields("id"):VALUE)
                ttPais.nome = ObjRecordSet:fields("nome"):VALUE
                ttPais.sigla = ObjRecordSet:fields("sigla"):VALUE.

            ASSIGN ODBC-CURSOR = ODBC-CURSOR + 1.
            ObjRecordSet:MoveNext NO-ERROR.
        END.
    END.
    ELSE
        ASSIGN ODBC-STATUS = "Nenhum registro localizado.".

    /* Processo para carregar Estados */
    assign ObjCommand:CommandText = "SELECT * FROM estado;".

    assign ObjRecordSet = ObjCommand:EXECUTE(,,) no-error.
    
    assign ODBC-RECCOUNT = ObjRecordSet:RecordCount.

    /* Se retornou registro */
    IF ODBC-RECCOUNT > 0
    AND ODBC-RECCOUNT <> ? then DO:
        ObjRecordSet:MoveFirst NO-ERROR.

        DO WHILE ODBC-CURSOR < ODBC-RECCOUNT:
            create ttEstado.
            assign
                ttEstado.id = integer(ObjRecordSet:fields("id"):VALUE)
                ttEstado.nome = ObjRecordSet:fields("nome"):VALUE
                ttEstado.uf = ObjRecordSet:fields("uf"):VALUE
                ttEstado.idPais = integer(ObjRecordSet:fields("pais"):VALUE).

            ASSIGN ODBC-CURSOR = ODBC-CURSOR + 1.
            ObjRecordSet:MoveNext NO-ERROR.
        END.
    END.
    ELSE
        ASSIGN ODBC-STATUS = "Nenhum registro localizado.".

    /* Processo para carregar Cidades */
    assign ObjCommand:CommandText = "SELECT * FROM cidade;".

    assign ObjRecordSet = ObjCommand:EXECUTE(,,) no-error.
    
    assign ODBC-RECCOUNT = ObjRecordSet:RecordCount.

    /* Se retornou registro */
    IF ODBC-RECCOUNT > 0
    AND ODBC-RECCOUNT <> ? then DO:
        ObjRecordSet:MoveFirst NO-ERROR.

        DO WHILE ODBC-CURSOR < ODBC-RECCOUNT:
            create ttCidade.
            assign
                ttCidade.id = integer(ObjRecordSet:fields("id"):VALUE)
                ttCidade.nome = ObjRecordSet:fields("nome"):VALUE
                ttCidade.idEstado = integer(ObjRecordSet:fields("estado"):VALUE).

            ASSIGN ODBC-CURSOR = ODBC-CURSOR + 1.
            ObjRecordSet:MoveNext NO-ERROR.
        END.
    END.
    ELSE
        ASSIGN ODBC-STATUS = "Nenhum registro localizado.".

    /* Processo para mostrar que alem de select tambem é possivel realizar insert, assim como update e delete */
    assign ObjCommand:CommandText = "INSERT INTO pais(nome, sigla) VALUES ('Argentina','AG');".

    assign ObjRecordSet = ObjCommand:EXECUTE(,,) no-error.

    /* Se retornou nenhum registro */
    IF integer(ODBC-NULL) <= 0
    OR ODBC-NULL = ? then DO:
        ASSIGN ODBC-STATUS = "Falha ao realzar INSERT.".
    END.
    
    /* Fecha conexao ADO */
    ObjConnection:CLOSE NO-ERROR.
END.

if ODBC-STATUS <> "" then do:
    MESSAGE 
        "Falha: " ODBC-STATUS
        VIEW-AS ALERT-BOX INFORMATION BUTTONS OK.
end.

RELEASE OBJECT ObjConnection NO-ERROR .
RELEASE OBJECT ObjCommand NO-ERROR .
RELEASE OBJECT ObjRecordSet NO-ERROR .

ASSIGN
    ObjConnection = ?
    ObjCommand = ?
    ObjRecordSet = ?.

for each ttPais no-lock
    ,each ttEstado no-lock
    where ttEstado.idPais = ttPais.id
    ,each ttCidade
    where ttCidade.idEstado = ttEstado.id
    no-lock:

    DISPLAY
        ttPais.nome column-label "Pais"
        ttEstado.nome format "x(18)" column-label "Estado"
        ttEstado.uf
        ttCidade.nome format "x(50)" column-label "Cidade"
        with width 500 no-box.
end.

Resultado ao executar o script acima:

Deixe um comentário

O seu endereço de e-mail não será publicado. Campos obrigatórios são marcados com *

Esse site utiliza o Akismet para reduzir spam. Aprenda como seus dados de comentários são processados.