oracle11G与10G网络通信差异

如有转载,请声明出处: 极致博客: http://blog.youkuaiyun.com/u011218159

这段时间经历太多太多,工作忙的不要不要的!感觉自己哪里都不在状态了,今天总算抽出了点时间总结下这个奇葩的问题了!这个问题的起因是得从从项目的初期开始说

了,作为一家外包公司一切的客户需求都必须的满足,即使是项目框架的设计也是如此;对于这个项目我真的是抹着泪给做完的 ...

客户是一位传统行业的老板,对于即将要上市的企业想做一款能够面向用户的APP,而且必须基于他们陈旧的、笨重的ERP开工,从此我就陷入水生火热之中了....

好像被我扯偏题了,废话就不想再说了,把问题说说吧:为了不污染他们的ERP所使用的oracle数据库,我们必须得做到ORACLE <——> MYSQL之间的同步;最开始想使用

OGG做数据库同步,但是担心时间来不及所幸使用了下面的方式简单处理了,毕竟我们只是需要ERP少量商品信息而已!通过触发器 ——> 存储过程 ——> http请求来做到同步 ... 

是不是觉得有点坑,这个都是次要的因为接下来是对问题进行处理!oracle11G与10G的网络通信所控制的粒度完全不一样,所以有下面的问题产生了!

错误样例(使用UTL_HTTP发送http请求时,报出如下错误):

ORA-29273: HTTP 请求失败
ORA-06512: 在 "SYS.UTL_HTTP", line 1130
ORA-24247: 网络访问被访问控制列表 (ACL) 拒绝
ORA-06512: 在 "YGMM.P_SENDSMS_TEST", line 15
ORA-06512: 在 line 3

原因:
1、Oracle允许使用几个PL/SQL API(UTL_TCP, UTL_SMTP, UTL_MAIL, UTL_HTTP和 UTL_INADDR)访问外部网络服务,这些API都使用TCP协议。
2、在Oracle 10g是通过一个基于用户是否被授予执行某个包的许可的 on/off开关来实现的,Oracle 11g引入了细粒度访问网络服务.
3、通过在XML DB 数据库中使用访问控制列表(ACL)来实现,允许控制哪个用户能够访问哪个网络资源,而不关心包的授权。

解决方案主要有如下几个步骤:

1. 查看用户是否有网络权限

<span style="font-family:Comic Sans MS;">--查看acl信息
SELECT acl,
       principal ,
       privilege,
       is_grant ,
       TO_CHAR (start_date , 'DD-MON-YYYY') AS start_date,
       TO_CHAR (end_date , 'DD-MON-YYYY') AS end_date
  FROM dba_network_acl_privileges ;

SELECT any_path FROM resource_view WHERE any_path like '%/sys/acls/%.xml%';
</span>
 

2.假如没有需要添加网络权限

<span style="font-family:Comic Sans MS;">--添加http请求,以principal:用户/角色,DRVTRAINING为用户
BEGIN
  dbms_network_acl_admin.create_acl (acl         => 'ygmm_http_request.xml',  -- 创建访问控制文件
                                    DESCRIPTION => 'Normal Access' ,           -- 描述
                                    principal   => 'YGMM',                    -- 授权或取消授权的账号
                                    is_grant    => TRUE,                      -- 授权还是取消授权
                                    PRIVILEGE   => 'connect',                 -- 授权或取消授权的权限列表
                                    start_date  => NULL,                      -- 开始生效日期
                                    end_date    => NULL);                     -- 截止失效日期
END;
</span>
 

3.添加访问权限列表

<span style="font-family:Comic Sans MS;">begin
 dbms_network_acl_admin.add_privilege (    -- 添加访问权限列表项
                                      acl        => 'ygmm_http_request.xml',           -- 刚才创建的acl名称
                                      principal  => 'YGMM',                    -- 授权或取消授权用户
                                      is_grant   => TRUE,                     -- 与上同
                                      privilege  => 'resolve',                -- 权限列表(解析)
                                      start_date => null,                   
                                      end_date   => null
                                    );
 end;
</span>
 
4.添加访问的地址和端口
<span style="font-family:Comic Sans MS;">--添加访问的地址,端口,DRVTRAINING为用户
begin
  dbms_network_acl_admin.assign_acl (
  acl        => 'ygmm_http_request.xml',
  host       => '120.76.42.206',            -- 访问主机
  lower_port => 21110,                      -- 最小访问端口
  upper_port => NULL);                      -- 最大访问端口
end;
</span>
 

5.测试访问是否OK

    在oracle11g中只有通过上面的设置拥有网路访问权限才能够进行http请求,http请求可以放在任何地方:存储过程、触发器、函数、代码块等;具体http请求代码如下:
 
<span style="font-family:Comic Sans MS;">create or replace procedure pr_synch_sendsms(
                                      p_businessType in varchar2,
                                      p_operatorCode in varchar2,
                                      p_mtSubID      in varchar2,
                                      err_code       out integer,
                                      ora_code       out integer) is
  s_request varchar2( 4000); --请求报文
  s_respond varchar2( 4000); --响应报文
  http_req  utl_http.req; --请求包头
  http_resp utl_http.resp; --响应包头
  s_sysdate varchar2( 30); --发送时间
BEGIN
  --取当前时间+1分钟
  select to_char (sysdate, 'YYYY-MM-DD' )||' '|| to_char( sysdate + 1 / 1440, 'hh24:mi:ss')
    INTO s_sysdate
    FROM DUAL;
  s_request := '{"businessType":"' ||p_businessType ||'","operatorCode":"'|| p_operatorCode||'","mtSubID":"' ||p_mtSubID ||'","sendtime":"'|| s_sysdate|| '"}';
  ---初始化REQUEST  ]
  http_req := utl_http.begin_request('http://120.25.68.86:21110/v2/oracle/synch/test',
                                     'POST',
                                     utl_http.HTTP_VERSION_1_1 /* 'HTTP/1.1'*/);
  utl_http.set_body_charset('UTF-8' );--设置包体编码集
    utl_http.set_header(http_req, 'Accept', '*/*');
  utl_http.set_header(http_req,
                      'Content-Type',
                      'application/json;charset=UTF-8');
  utl_http.set_header(http_req,
                      'User-Agent',
                      'Nimo Software HTTP Retriever 1.0');
  utl_http.set_header(http_req, 'Content-Length', length (s_request ));
  utl_http.set_header(http_req, 'Cache-Control', 'no-cache' );
  utl_http.write_text(http_req, s_request);--如果有包体可以写入json数据,关键需要和Content-type相互对应
  http_resp := utl_http.get_response (http_req ); --提交请求
 
  if http_resp.status_code = utl_http.HTTP_OK then
    --成功才读取响应消息
    utl_http.read_text(http_resp, s_respond);
    utl_http.end_response (http_resp ); --结束请求
    s_respond := substr( s_respond, 1 , 4000); ---long 转成 varchar2
    dbms_output.put_line (s_respond ); --打印响应消息
    dbms_output.put_line (http_resp.reason_phrase ); --打印响应消息
  else
    err_code := http_resp.status_code ;
    ora_code := sqlcode;
    dbms_output.put_line (http_resp.reason_phrase ); --打印响应消息
  end if;
exception
  WHEN OTHERS THEN
    ora_code := sqlcode;
END;

注意:oracle中的¶m表示一个变量的意思,所以在oracle中想使用&必须要&&才可以表示
</span>

说明:
如有博友觉得本人博文有需要更正的地方,还望能够指教一下!
   我的邮箱:lvyongwenhouzi@qq.com
   新浪微博:@lenny呂         
   QQ/微信号:854588035/Y-lenny
   2016年3月23日
By lenny

 

 


 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值