Invoking Webservice from PL/SQL (UTL_DBWS&UTL_HTTP)

从PL/SQL,Oracle提供了两种方式调用外部Webservice:一种是UTL_HTTP,另外一种是UTL_DBWS。
  • utl_http – low level http assembler
  • utl_dbws – high level web service package

UTL_HTTP

•Available as of 8.0.5
•Send/receive raw HTTP request/responses to external servers
•Advantages:
Simplistic
–Installed (completely) in the database
–Passed and returns a VARCHAR2 XML payload
–Very easy if you know the XML payload structures
–Doesn't require a WSDL at publisher's site
–Good examples available on the internet
–3 rdparty PL/SQL wrappers available (Tim Hall:  soap_api)
•Disadvantages:
–Low level with no smarts to support web services
–Cryptic HTTP error messages
Oracle documentation is less than useful

UTL_DBWS

  • Available as of 10gR1
  • PL/SQL Java wrapper on oracle.jpub.runtime.dbws.DbwsProxy
  • Part of JPublisher
  • Advantages:
                    - High(er) level web service handler

  • Disadvantages:
-Not completely installed by default (bah!)
-Poor error reporting (in particular HTTP)
-Queries external WSDL each request
-Oracle documentation is dismal
-Use of HttpUriType does not support wallets or proxies
-Minor bugs in 10gR2 version with external authentication
-Minor issues on calling .Net web services
-Uses database JVM

UTL_HTTP现在已经逐步取代UTL_DBWS。

UTL_HTTP Sample


DECLARE
  L_PARAM_LIST VARCHAR2(512);

  L_HTTP_REQUEST  UTL_HTTP.REQ;
  L_HTTP_RESPONSE UTL_HTTP.RESP;

  L_RESPONSE_TEXT VARCHAR2(32767);
BEGIN

  -- service's input parameters
  L_PARAM_LIST := 'FromCurrency=EUR&ToCurrency=USD';

  -- preparing Request...
  L_HTTP_REQUEST := UTL_HTTP.BEGIN_REQUEST('http://www.webservicex.net/currencyconvertor.asmx/ConversionRate',
                                           'POST',
                                           'HTTP/1.1');

  -- ...set header's attributes
  UTL_HTTP.SET_HEADER(L_HTTP_REQUEST,
                      'Content-Type',
                      'application/x-www-form-urlencoded');
  UTL_HTTP.SET_HEADER(L_HTTP_REQUEST,
                      'Content-Length',
                      LENGTH(L_PARAM_LIST));

  -- ...set input parameters
  UTL_HTTP.WRITE_TEXT(L_HTTP_REQUEST, L_PARAM_LIST);

  -- get Response and obtain received value
  L_HTTP_RESPONSE := UTL_HTTP.GET_RESPONSE(L_HTTP_REQUEST);

  UTL_HTTP.READ_TEXT(L_HTTP_RESPONSE, L_RESPONSE_TEXT);

  DBMS_OUTPUT.PUT_LINE(L_RESPONSE_TEXT);

  -- finalizing
  UTL_HTTP.END_RESPONSE(L_HTTP_RESPONSE);

EXCEPTION
  WHEN UTL_HTTP.END_OF_BODY THEN
    UTL_HTTP.END_RESPONSE(L_HTTP_RESPONSE);
END;

UTL_DBWS Sample

 DECLARE
   v_namespace        VARCHAR2(1000) := 'http://www.sagecomputing.com.au/emp';
   v_service_qname    utl_dbws.qname := utl_dbws.to_qname(v_namespace,'employees');
   v_port_qname       utl_dbws.qname := utl_dbws.to_qname(v_namespace,'employeesSoapHttpPort');
   v_operation_qname  utl_dbws.qname := utl_dbws.to_qname(v_namespace,'getName');

   v_service           utl_dbws.service;
   v_call              utl_dbws.call;

   v_int_type          utl_dbws.qname;
   v_string_type       utl_dbws.qname;

   v_request_params    utl_dbws.anydata_list; -- RPC style only
   v_response_anydata  AnyData;               -- RPC style only

   v_request_xmltype   XmlType;               -- Document style only
   v_response_xmltype  XmlType;               -- Document style only   

BEGIN
   v_service := utl_dbws.create_service(
     HttpUriType('http://www.sage.com.au/employees?wsdl'), v_service_qname);

   v_call := utl_dbws.create_call(v_service, v_port_qname, v_operation_qname);

   utl_dbws.set_property(v_call, 'SOAPACTION_USE',    'TRUE');
   utl_dbws.set_property(v_call, 'SOAPACTION_URI',    'getName');
   utl_dbws.set_property(v_call, 'ENCODINGSTYLE_URI',
    'http://schemas.xmlsoap.org/soap/encoding/');  
   utl_dbws.set_property(v_call, 'OPERATION_STYLE',   'rpc');

   utl_dbws.set_property(v_call, 'OPERATION_STYLE',   'document');
   utl_dbws.set_property(v_call, 'OPERATION_STYLE',   'rpc');

   v_int_type    := utl_dbws.to_qname('http://www.w3.org/2001/XMLSchema', 'int');
   v_string_type := utl_dbws.to_qname('http://www.w3.org/2001/XMLSchema', 'string');

   utl_dbws.add_parameter(v_call, 'employeeNumber', v_int_type,    'ParameterMode.IN');
   utl_dbws.add_parameter(v_call, 'nameCase',       v_string_type, 'ParameterMode.IN');
   utl_dbws.set_return_type(v_call, v_string_type);  

   v_request_params(0) := AnyData.convertNumber(1234);
   v_request_params(1) := AnyData.convertVarchar('M');

   v_response_anydata := utl_dbws.invoke(v_call, v_request_params);
   dbms_output.put_line('Result = ' || v_response_anydata.accessVarchar2);

   utl_dbws.release_call(v_call);
   utl_dbws.release_service(v_service);
END;
/
Result = Christopher Muir


<think>嗯,用户遇到了CMake的错误,具体是在处理livox_ros_driver这个包的时候。错误信息显示在version.cmake文件的第4行,尝试打开livox_ros_driver.h头文件时失败,因为这个文件不存在。接着在version.cmake的第14行抛出了一个错误,说无法从该头文件中提取有效的版本号,导致配置失败。 首先,我需要理解这个错误的原因。CMake在构建过程中会执行一些脚本,这里提到的version.cmake脚本试图读取头文件来获取版本信息。但问题在于头文件的路径不对,或者头文件确实缺失了。可能的原因有几个:文件路径错误、文件被移动或删除、仓库克隆不完整,或者权限问题。 接下来,我应该考虑用户可能的操作背景。用户可能是在尝试编译某个ROS(机器人操作系统)项目,特别是涉及到Livox激光雷达的驱动。Livox ROS驱动可能需要从GitHub克隆,然后使用catkin_make或catkin build进行构建。常见的错误包括仓库没有正确克隆,或者子模块未初始化。 首先,检查文件路径是否正确。根据错误信息,头文件的预期路径是/home/wpb/ws_livox/src/livox_ros_driver-master/livox_ros_driver/cmake/../livox_ros_driver/include/livox_ros_driver.h。这里的“cmake/..”表示回到上一级目录,也就是livox_ros_driver目录,然后进入include文件夹。所以实际路径应该是/home/wpb/ws_livox/src/livox_ros_driver-master/livox_ros_driver/include/livox_ros_driver.h。用户需要确认这个路径下是否存在该文件。 如果文件不存在,可能的原因包括: 1. 仓库未正确克隆:用户可能只克隆了主仓库,但没有下载子模块,或者克隆时中断导致文件缺失。 2. 文件被误删或移动:用户可能在项目中进行了一些文件操作,不小心移动或删除了头文件。 3. 仓库结构变化:可能驱动程序的仓库结构有更新,导致旧版本的CMake脚本无法找到新路径下的文件。 解决方案的第一步是让用户检查文件是否存在。如果不存在,需要重新克隆仓库,确保使用正确的命令,比如递归克隆以包含子模块。例如,使用git clone --recursive <repo-url>来确保所有子模块都被下载。 另外,用户可能没有正确放置仓库。ROS的工作空间通常要求包放在src目录下,并且路径结构正确。用户需要确认livox_ros_driver的目录结构是否符合要求,特别是include文件夹的位置。 如果文件存在但路径不对,可能需要修改CMakeLists.txt或version.cmake中的路径引用,确保相对路径正确。或者,用户可能将仓库放在了错误的目录下,导致相对路径解析错误。 还有一种可能性是版本号提取失败,即头文件存在,但里面的版本信息格式不符合CMake脚本的预期。这时候需要检查头文件中版本号的格式,是否匹配脚本中的正则表达式或提取逻辑。例如,脚本可能期望类似#define LIVOX_ROS_DRIVER_VERSION "1.0.0"这样的行,而实际头文件中的写法不同,导致提取失败。 此外,用户可能需要清理构建目录并重新编译。有时候旧的构建文件会导致问题,删除build、devel、install目录后重新运行catkin_make可以解决路径问题。 最后,权限问题也不能完全排除,尽管可能性较低。用户需要检查是否有读取头文件的权限,但通常克隆下来的文件应该具有正确权限。 总结,解决步骤应该是: 1. 确认头文件是否存在。 2. 检查仓库克隆是否正确,包括子模块。 3. 检查CMake脚本中的路径是否正确。 4. 清理构建目录并重新编译。 5. 检查头文件中的版本信息格式。</think>在编译Livox ROS驱动时遇到的CMake错误通常由头文件路径缺失或版本信息解析失败导致。以下是逐步排查和解决方案: --- ### **1. 错误原因分析** 错误信息显示CMake在以下路径找不到头文件: $$ \text{/home/wpb/ws\_livox/src/livox\_ros\_driver-master/livox\_ros\_driver/include/livox\_ros\_driver.h} $$ 且无法从该文件中提取版本号。可能原因: - **文件未正确克隆**:Git仓库未完整下载(如缺少子模块)。 - **路径错误**:文件实际路径与CMake脚本预期路径不匹配。 - **版本格式问题**:头文件中的版本号格式不符合CMake解析规则。 --- ### **2. 解决方案步骤** #### **(1) 确认头文件是否存在** 执行以下命令检查文件是否存在: ```bash # 进入头文件预期路径 cd /home/wpb/ws_livox/src/livox_ros_driver-master/livox_ros_driver/include/ ls -l livox_ros_driver.h ``` - **如果文件存在**:跳转到步骤3。 - **如果文件不存在**:继续下一步。 --- #### **(2) 重新克隆仓库** Livox ROS驱动可能需要递归克隆子模块。执行以下命令: ```bash # 删除旧仓库(备份重要修改) cd ~/ws_livox/src rm -rf livox_ros_driver-master # 重新克隆(注意添加 --recursive) git clone --recursive https://github.com/Livox-SDK/livox_ros_driver.git ``` --- #### **(3) 检查CMake脚本路径** 打开文件 `version.cmake`(位于 `livox_ros_driver/cmake/`),检查以下代码段: ```cmake # 原代码可能类似: file(READ "${CMAKE_CURRENT_LIST_DIR}/../include/livox_ros_driver.h" DRIVER_H_CONTENTS) ``` - 确保 `${CMAKE_CURRENT_LIST_DIR}/../include/` 实际指向头文件目录。 - 若路径不符,修改为绝对路径(不推荐)或调整相对路径。 --- #### **(4) 检查版本号格式** 打开 `livox_ros_driver.h`,确认版本号定义格式是否为以下模式: ```cpp #define LIVOX_ROS_DRIVER_VERSION "x.x.x" # 例如 "2.6.0" ``` - 若格式不符(如缺少宏定义),需手动添加或同步仓库最新代码。 --- #### **(5) 清理并重新编译** ```bash # 删除构建缓存 cd ~/ws_livox rm -rf build devel install # 重新编译 catkin_make -j4 ``` --- ### **3. 补充建议** - **子模块初始化**:如果仓库包含子模块,需额外执行: ```bash git submodule update --init --recursive ``` - **权限问题**:确保用户对文件有读取权限: ```bash chmod -R 755 ~/ws_livox/src/livox_ros_driver-master ``` - **版本兼容性**:检查ROS版本(如Melodic/Noetic)与Livox驱动的兼容性。 --- ### **4. 结果验证** 若操作无误,重新编译后应不再报错。如果问题持续,请检查 `CMakeError.log` 和 `CMakeOutput.log` 中的详细错误信息: ```bash less /home/wpb/ws_livox/build/CMakeFiles/CMakeError.log ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值