Nessa publicação iremos ver como podemos importar os estados e municípios do Brasil usando a API gratuita do IBGE.gov.br em nosso banco Oracle 😄.
Iremos seguir a criação do seguinte modelo de dados:
Execute o código DDL abaixo para criar as tabelas que iremos precisar:
CREATE TABLE estados (
id_estado NUMBER NOT NULL,
sigla CHAR(2 BYTE),
nome VARCHAR2(1000 BYTE),
regiao VARCHAR2(100 BYTE)
);
ALTER TABLE estados ADD CONSTRAINT estados_pk PRIMARY KEY ( id_estado );
CREATE TABLE municipios (
id_municipio NUMBER NOT NULL,
nome VARCHAR2(2000 BYTE),
mesorregiao VARCHAR2(600 BYTE),
id_estado NUMBER NOT NULL
);
ALTER TABLE municipios ADD CONSTRAINT municipios_pk PRIMARY KEY ( id_municipio );
ALTER TABLE municipios
ADD CONSTRAINT municipios_estados_fk FOREIGN KEY ( id_estado )
REFERENCES estados ( id_estado );
Importando Estados
A URL da API que iremos utilizar é https://servicodados.ibge.gov.br/api/v1/localidades/estados. Ela retorna um JSON com os dados no seguinte formato:
{
"id": 11,
"sigla": "RO",
"nome": "Rondônia",
"regiao": {
"id": 1,
"sigla": "N",
"nome": "Norte"
}
Basta rodar o script abaixo para importar os estados em nossa tabela:
DECLARE
v_clob CLOB;
BEGIN
v_clob := apex_web_service.make_rest_request(
p_url => 'https://servicodados.ibge.gov.br/api/v1/localidades/estados',
p_http_method => 'GET'
);
FOR i IN (
SELECT
jt.*
FROM
JSON_TABLE ( v_clob, '$[*]'
COLUMNS (
row_number FOR ORDINALITY,
id NUMBER PATH '$.id',
sigla VARCHAR2 ( 2 ) PATH '$.sigla',
nome VARCHAR2 ( 1000 ) PATH '$.nome',
regiao VARCHAR2 ( 600 ) PATH '$.regiao.nome'
)
)
AS jt
) LOOP
INSERT INTO estados (
id_estado,
sigla,
nome,
regiao
) VALUES (
i.id,
i.sigla,
i.nome,
i.regiao
);
END LOOP;
COMMIT;
END;
Importando municípios
A URL da API que iremos utilizar é https://servicodados.ibge.gov.br/api/v1/localidades/municipios. Ela retorna um JSON com os dados no seguinte formato:
{
"id": 1100015,
"nome": "Alta Floresta D'Oeste",
"microrregiao": {
"id": 11006,
"nome": "Cacoal",
"mesorregiao": {
"id": 1102,
"nome": "Leste Rondoniense",
"UF": {
"id": 11,
"sigla": "RO",
"nome": "Rondônia",
"regiao": {
"id": 1,
"sigla": "N",
"nome": "Norte"
}
}
}
},
"regiao-imediata": {
"id": 110005,
"nome": "Cacoal",
"regiao-intermediaria": {
"id": 1102,
"nome": "Ji-Paraná",
"UF": {
"id": 11,
"sigla": "RO",
"nome": "Rondônia",
"regiao": {
"id": 1,
"sigla": "N",
"nome": "Norte"
}
}
}
}
}
Basta rodar o script abaixo para importar os municipios em nossa tabela:
DECLARE
v_clob CLOB;
v_count NUMBER;
BEGIN
v_clob := apex_web_service.make_rest_request(
p_url => 'https://servicodados.ibge.gov.br/api/v1/localidades/municipios',
p_http_method => 'GET'
);
FOR i IN (
SELECT
jt.*
FROM
JSON_TABLE ( v_clob, '$[*]'
COLUMNS (
row_number FOR ORDINALITY,
id NUMBER PATH '$.id',
nome VARCHAR2 ( 4000 ) PATH '$.nome',
mesorregiao VARCHAR2 ( 4000 ) PATH '$.microrregiao.mesorregiao.nome',
id_estado NUMBER PATH '$.microrregiao.mesorregiao.UF.id'
)
)
AS jt
) LOOP
SELECT
COUNT(*)
INTO v_count
FROM
municipios m
WHERE
m.id_municipio = i.id;
IF v_count = 0 THEN
INSERT INTO municipios (
id_municipio,
nome,
mesorregiao,
id_estado
) VALUES (
i.id,
i.nome,
i.mesorregiao,
i.id_estado
);
END IF;
END LOOP;
COMMIT;
END;
Utilizando a UTL_HTTP para requisições REST
Caso não tenha o APEX instalado em seu banco Oracle, não tem problema! Basta
alguns ajustes para utilizamos a UTL_HTTP.
Primeiramente precisamos habilitar os serviços de network no banco, caso contrário irá dar o erro ORA-44416: Invalid ACL - ajuste
o parâmetro principal_name com o nome do schema que irá rodar o
script e execute como SYSDBA:
BEGIN
DBMS_NETWORK_ACL_ADMIN.APPEND_HOST_ACE(
host => '*',
ace => xs$ace_type(privilege_list => xs$name_list('connect'),
principal_name => 'SEU_SCHEMA',
principal_type => xs_acl.ptype_db));
END;
/
Agora rodamos nosso script com a UTL_HTTP:
DECLARE
v_clob CLOB;
v_count NUMBER;
request_context utl_http.request_context_key;
req utl_http.req;
res utl_http.resp;
buffer varchar2(32767);
BEGIN
request_context := UTL_HTTP.CREATE_REQUEST_CONTEXT(
wallet_path => 'file:/home/oracle/wallets/wallet',
wallet_password => 'suasenha');
req := UTL_HTTP.BEGIN_REQUEST(
url => 'https://servicodados.ibge.gov.br/api/v1/localidades/municipios',
method => 'GET',
request_context => request_context);
UTL_HTTP.SET_HEADER (
req,
'Content-Type',
'application/json; charset=utf-8');
UTL_HTTP.SET_BODY_CHARSET (
charset => 'UTF-8');
res := UTL_HTTP.GET_RESPONSE(req);
begin
loop
utl_http.read_text(res, buffer,32767);
v_clob := v_clob || buffer;
end loop;
utl_http.end_response(res);
exception
when utl_http.end_of_body
then
utl_http.end_response(res);
end;
UTL_HTTP.END_REQUEST(req);
FOR i IN (
SELECT
jt.*
FROM
JSON_TABLE ( v_clob, '$[*]'
COLUMNS (
row_number FOR ORDINALITY,
id NUMBER PATH '$.id',
nome VARCHAR2 ( 4000 ) PATH '$.nome',
mesorregiao VARCHAR2 ( 4000 ) PATH '$.microrregiao.mesorregiao.nome',
id_estado NUMBER PATH '$.microrregiao.mesorregiao.UF.id'
)
)
AS jt
) LOOP
SELECT
COUNT(*)
INTO v_count
FROM
municipios m
WHERE
m.id_municipio = i.id;
IF v_count = 0 THEN
INSERT INTO municipios (
id_municipio,
nome,
mesorregiao,
id_estado
) VALUES (
i.id,
i.nome,
i.mesorregiao,
i.id_estado
);
END IF;
END LOOP;
COMMIT;
END;
Tratando erro de certificado ORA-29024
Ao executar o script acima, pode ocorrer o seguinte erro:
ORA-29273: falha na solicitação HTTP
ORA-06512: em "APEX_220100.WWV_FLOW_WEB_SERVICES", line 1182
ORA-06512: em "APEX_220100.WWV_FLOW_WEB_SERVICES", line 782
ORA-29024: Falha de validação de certificado
ORA-06512: em "SYS.UTL_HTTP", line 380
ORA-06512: em "SYS.UTL_HTTP", line 1148
ORA-06512: em "APEX_220100.WWV_FLOW_WEB_SERVICES", line 756
ORA-06512: em "APEX_220100.WWV_FLOW_WEB_SERVICES", line 1023
ORA-06512: em "APEX_220100.WWV_FLOW_WEB_SERVICES", line 1371
ORA-06512: em "APEX_220100.WWV_FLOW_WEBSERVICES_API", line 568
ORA-06512: em line 5
29273. 00000 - "HTTP request failed"
*Cause: The UTL_HTTP package failed to execute the HTTP request.
*Action: Use get_detailed_sqlerrm to check the detailed error message.
Fix the error and retry the HTTP request.
Para corrigir esse erro, precisamos criar uma wallet e adicionar o certificado
root do domínio https://servicodados.ibge.gov.br que estamos acessando.
Caso esteja usando o Oracle Apex, adicione em uma wallet que já esteja
configurar em sua instância. Caso não seja seu caso, adicione os parâmetros
p_wallet_path (file:/home/oracle/wallets/wallet) e
p_wallet_pwd na chamada da apex_web_service.make_rest_request.
v_clob := apex_web_service.make_rest_request(
p_url => 'https://servicodados.ibge.gov.br/api/v1/localidades/municipios',
p_http_method => 'GET',
p_wallet_path => 'file:/home/oracle/wallets/wallet',
p_wallet_pwd => 'suasenha'
);
Parar criar a wallet execute o comando abaixo em seu servidor no qual o banco esteja instalado - conecte como usuário root ou oracle no Linux (ajuste a senha da wallet):
orapki wallet create -wallet /home/oracle/wallets/wallet -pwd suasenha
Resultado esperado:
Oracle PKI Tool Release 21.0.0.0.0 - Production
Version 21.3.0.0.0
Copyright (c) 2004, 2021, Oracle and/or its affiliates. All rights reserved.
Operation is successfully completed.
Obtenha os certificados do dominio e salve o segundo certificado (2 s:C = US,
ST = New Jersey, L = Jersey City, O = The USERTRUST Network, CN = USERTrust
RSA Certification Authority) a partir do -----BEGIN CERTIFICATE----- até o
-----END CERTIFICATE----- em um arquivo com a extenção .pem:
openssl s_client -showcerts -verify 5 -connect servicodados.ibge.gov.br:443
Salvei o arquivo em /home/oracle/wallets/ibge.pem.E agora adicionamos o certificado:
orapki wallet add -wallet /home/oracle/wallets/wallet -trusted_cert -cert /home/oracle/wallets/ibge.pem
Resultado esperado:
Oracle PKI Tool Release 21.0.0.0.0 - Production
Version 21.3.0.0.0
Copyright (c) 2004, 2021, Oracle and/or its affiliates. All rights reserved.
Enter wallet password:
Operation is successfully completed.
Pronto, basta rodar os scripts agora.
Comentários
Postar um comentário