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