You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何从PL/SQL过程连接SOAP Web服务?求简单示例脚本

PL/SQL调用SOAP Web服务流程与示例

实现流程

  • 1. 收集Web服务核心信息:先拿到目标SOAP服务的端点URL(Endpoint)、WSDL文档,明确请求的SOAP信封格式、参数位置、命名空间,以及SOAPAction头的值。
  • 2. 配置数据库网络权限:如果数据库服务器无法访问外部网络,需要DBA通过DBMS_NETWORK_ACL_ADMIN包配置访问控制列表(ACL),允许你的数据库用户访问Web服务所在的域名和端口。
  • 3. 发送HTTP POST请求:用PL/SQL自带的UTL_HTTP包构造并发送POST请求,设置正确的请求头(比如Content-Type为text/xml),写入构造好的SOAP请求体。
  • 4. 解析响应结果:服务返回的是XML格式的SOAP响应,用XMLTYPE或DBMS_XMLDOM工具提取你需要的结果数据。

示例脚本

以下是一个可传递参数、返回计算结果的PL/SQL过程示例,假设调用一个实现两数相加的SOAP Web服务:

DECLARE
  -- 定义HTTP请求/响应对象
  l_http_req  UTL_HTTP.REQ;
  l_http_res  UTL_HTTP.RESP;
  -- Web服务端点URL(替换为实际地址)
  l_service_url VARCHAR2(200) := 'http://example.com/CalculatorService';
  -- SOAP请求信封
  l_soap_body VARCHAR2(32767);
  -- 存储响应内容
  l_response_text VARCHAR2(32767);
  -- 存储解析后的结果
  l_calc_result NUMBER;
BEGIN
  -- 1. 构造SOAP请求体,替换参数值
  l_soap_body := '<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:calc="http://example.com/calculator">
                     <soapenv:Header/>
                     <soapenv:Body>
                        <calc:Add>
                           <calc:num1>15</calc:num1> -- 第一个加数
                           <calc:num2>25</calc:num2> -- 第二个加数
                        </calc:Add>
                     </soapenv:Body>
                  </soapenv:Envelope>';

  -- 2. 初始化HTTP POST请求
  l_http_req := UTL_HTTP.BEGIN_REQUEST(l_service_url, 'POST');
  
  -- 设置请求头
  UTL_HTTP.SET_HEADER(l_http_req, 'Content-Type', 'text/xml; charset=utf-8');
  UTL_HTTP.SET_HEADER(l_http_req, 'SOAPAction', 'http://example.com/calculator/Add'); -- 替换为实际SOAPAction
  UTL_HTTP.SET_HEADER(l_http_req, 'Content-Length', LENGTH(l_soap_body));

  -- 3. 发送SOAP请求体
  UTL_HTTP.WRITE_TEXT(l_http_req, l_soap_body);
  
  -- 4. 获取服务响应
  l_http_res := UTL_HTTP.GET_RESPONSE(l_http_req);
  
  -- 读取响应内容
  UTL_HTTP.READ_TEXT(l_http_res, l_response_text);
  
  -- 关闭请求/响应连接
  UTL_HTTP.END_RESPONSE(l_http_res);
  UTL_HTTP.END_REQUEST(l_http_req);

  -- 5. 解析SOAP响应,提取计算结果
  -- 假设响应格式为 <AddResponse><AddResult>40</AddResult></AddResponse>
  l_calc_result := XMLTYPE(l_response_text).extract('//AddResult/text()').getNumberVal();
  
  -- 输出结果
  DBMS_OUTPUT.PUT_LINE("两数相加结果: " || l_calc_result);
  
EXCEPTION
  WHEN UTL_HTTP.END_OF_BODY THEN
    -- 处理响应提前结束的情况
    IF UTL_HTTP.IS_OPEN(l_http_res) THEN
      UTL_HTTP.END_RESPONSE(l_http_res);
    END IF;
    IF UTL_HTTP.IS_OPEN(l_http_req) THEN
      UTL_HTTP.END_REQUEST(l_http_req);
    END IF;
  WHEN OTHERS THEN
    DBMS_OUTPUT.PUT_LINE("错误信息: " || SQLERRM);
    -- 确保关闭连接
    IF UTL_HTTP.IS_OPEN(l_http_res) THEN
      UTL_HTTP.END_RESPONSE(l_http_res);
    END IF;
    IF UTL_HTTP.IS_OPEN(l_http_req) THEN
      UTL_HTTP.END_REQUEST(l_http_req);
    END IF;
    RAISE;
END;
/

关键注意事项

  • ACL权限配置:如果运行时出现ORA-24247: network access denied by access control list (ACL)错误,需要DBA执行以下脚本配置权限(替换为实际信息):
    BEGIN
      DBMS_NETWORK_ACL_ADMIN.CREATE_ACL(
        acl         => 'soap_service_acl.xml',
        description => '允许访问SOAP Web服务',
        principal   => '你的数据库用户名',
        is_grant    => TRUE,
        privilege   => 'connect'
      );
      DBMS_NETWORK_ACL_ADMIN.ASSIGN_ACL(
        acl         => 'soap_service_acl.xml',
        host        => 'example.com', -- Web服务域名
        lower_port  => 80, -- 服务端口
        upper_port  => 80
      );
      COMMIT;
    END;
    /
    
  • SOAP格式严格匹配:必须完全按照目标服务的WSDL定义构造请求信封,包括命名空间、参数标签名,否则服务会返回格式错误。
  • 字符集处理:如果响应包含中文或特殊字符,可通过UTL_HTTP.SET_CHARSET(l_http_res, 'UTF8')设置字符集,避免乱码。

内容的提问来源于stack exchange,提问作者Harikrishnan Anilkumar

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.11 05:35:16