当前位置: 首页 > 面试题库 >

在oracle中使用json

訾高飞
2023-03-14
问题内容

有没有一种简单的方法可以在Oracle中使用JSON?我有一个经常用于调用Web服务的标准过程,JSON是我在Web开发上下文中熟悉的一种格式,但是在存储过程中使用JSON的最佳方法是什么?例如,从URI中获取CLOB响应,将其转换为JSON对象并从中获取值?

作为参考,这是我用来获取URL的过程

create or replace procedure macp_URL_GET(url_resp in out clob, v_url in varchar2) is
   req     Utl_Http.req;
   resp    Utl_Http.resp;
   NAME    VARCHAR2 (255);
   VALUE   VARCHAR2 (1023);
   v_msg   VARCHAR2 (80);
   v_ans clob;
--   v_url   VARCHAR2 (32767) := 'http://www.macalester.edu/';
BEGIN
   /* request that exceptions are raised for error Status Codes */
   Utl_Http.set_response_error_check (ENABLE => TRUE );
   /* allow testing for exceptions like Utl_Http.Http_Server_Error */
   Utl_Http.set_detailed_excp_support (ENABLE => TRUE );
   /*
   Utl_Http.set_proxy (
      proxy                 => 'www-proxy.us.oracle.com',
      no_proxy_domains      => 'us.oracle.com'
   );
   */
   req := Utl_Http.begin_request (url => v_url, method => 'GET');
   /*
    Alternatively use method => 'POST' and Utl_Http.Write_Text to
    build an arbitrarily long message
  */

  /*
   Utl_Http.set_authentication (
      r              => req,
      username       => 'SomeUser',
      PASSWORD       => 'SomePassword',
      scheme         => 'Basic',
      for_proxy      => FALSE      --this info is for the target Web server 
   );
   */

   Utl_Http.set_header (r => req, NAME => 'User-Agent', VALUE => 'Mozilla/4.0');
   resp := Utl_Http.get_response (r => req);
   /*
   DBMS_OUTPUT.put_line ('Status code: ' || resp.status_code);
   DBMS_OUTPUT.put_line ('Reason phrase: ' || resp.reason_phrase);
   FOR i IN 1 .. Utl_Http.get_header_count (r => resp)
   LOOP
      Utl_Http.get_header (r => resp, n => i, NAME => NAME, VALUE => VALUE);
      DBMS_OUTPUT.put_line (NAME || ': ' || VALUE);
   END LOOP;
   */
--test
   BEGIN
      LOOP
         Utl_Http.read_text (r => resp, DATA => v_msg);
         --DBMS_OUTPUT.put_line (v_msg);
         v_ans := v_ans || v_msg;
         url_resp := url_resp || v_msg;
      END LOOP;
   EXCEPTION
      WHEN Utl_Http.end_of_body
      THEN
         NULL;
   END;
--test
   Utl_Http.end_response (r => resp);


   --url_resp := v_ans;

EXCEPTION
   /*
    The exception handling illustrates the use of "pragma-ed" exceptions
    like Utl_Http.Http_Client_Error. In a realistic example, the program
    would use these when it coded explicit recovery actions.

    Request_Failed is raised for all exceptions after calling
    Utl_Http.Set_Detailed_Excp_Support ( ENABLE=>FALSE )
    And it is NEVER raised after calling with ENABLE=>TRUE
  */
   WHEN Utl_Http.request_failed
   THEN
      DBMS_OUTPUT.put_line (
         'Request_Failed: ' || Utl_Http.get_detailed_sqlerrm
      );
      url_resp :='Request_Failed: ' || Utl_Http.get_detailed_sqlerrm;
   /* raised by URL http://xxx.oracle.com/ */
   WHEN Utl_Http.http_server_error
   THEN
      DBMS_OUTPUT.put_line (
         'Http_Server_Error: ' || Utl_Http.get_detailed_sqlerrm
      );
      url_resp := 'Http_Server_Error: ' || Utl_Http.get_detailed_sqlerrm;
   /* raised by URL http://otn.oracle.com/xxx */
   WHEN Utl_Http.http_client_error
   THEN
      DBMS_OUTPUT.put_line (
         'Http_Client_Error: ' || Utl_Http.get_detailed_sqlerrm
      );
      url_resp := 'Http_Client_Error: ' || Utl_Http.get_detailed_sqlerrm;
   /* code for all the other defined exceptions you can recover from */
   WHEN OTHERS
   THEN
      DBMS_OUTPUT.put_line (SQLERRM);
      url_resp := SQLERRM;
END;

然后测试

begin
  macp_url_get(url_resp => :url_resp,
               'http://maps.googleapis.com/maps/api/geocode/json?address=55105&sensor=false');
end;

(我知道googleapi将允许xml响应,但我经常使用其他一些默认为JSON的Web API)


问题答案:

我已经开始使用该库,并且看起来很有希望:https :
//github.com/pljson/pljson

易于安装,示例很好。

要在示例中使用该库,请将这些变量添加到过程中。

mapData     json;
results     json_list;
status      json_value;
firstResult json;
geometry    json;

....

然后,您可以将响应作为json对象操作。

-- convert the result from the get to a json object, and show some results.
mapData := json(v_ans);

-- Show the status of the request
status := mapData.get('status');
dbms_output.put_line('Status = ' || status.get_string());

IF (status.get_string() = 'OK') THEN
  results := json_list(mapData.get('results'));
  -- Grab the first item in the list
  resultObject := json(results.head);

  -- Show the human readable address 
  dbms_output.put_line('Address = ' || resultObject.get('formatted_address').to_char() );
  -- Show the json location data 
  dbms_output.put_line('Location = ' || resultObject.get('geometry').to_char() );
END IF;

运行以下代码会将其输出到dbms输出:

Status = OK
Address = "St Paul, MN 55105, USA"
Location = {
  "bounds" : {
    "northeast" : {
      "lat" : 44.9483849,
      "lng" : -93.1261959
    },
    "southwest" : {
      "lat" : 44.9223829,
      "lng" : -93.200307
    }
  },
  "location" : {
    "lat" : 44.9330076,
    "lng" : -93.16290629999999
  },
  "location_type" : "APPROXIMATE",
  "viewport" : {
    "northeast" : {
      "lat" : 44.9483849,
      "lng" : -93.1261959
    },
    "southwest" : {
      "lat" : 44.9223829,
      "lng" : -93.200307
    }
  }
}


 类似资料:
  • 问题内容: 我在一次采访中遇到了这个问题,不知道如何回答: 有一个表在列上有一个索引,您可以查询: 该查询花费的时间太长,您发现该索引没有被使用。如果您认为使用索引将使查询的性能更好,那么如何强制查询使用索引呢? 问题答案: 您可以使用优化程序提示 等等… 有关使用优化程序提示的更多信息:http : //download.oracle.com/docs/cd/B19306_01/server.1

  • 我有ORACLE DB和2个表。我需要从表1内部连接表2中选择行,并按ORACLE RowID列排序。要选择,我使用条件查询。要添加我使用的order by语句 在映射中,RowId看起来像 但是hibernate生成错误的sql查询,如 Hibernate从查询中删除别名“this”。因为ORACLE中的所有表都有ROWID列,所以我们有Oracle错误ORA-00918 如何按hibernat

  • 问题内容: 我的表的列为,数据类型为“ DATE”。此列中的数据以方式存储。 现在,我正在尝试通过此查询获取数据: 不知何故它不起作用,我也不知道为什么。 希望有人能帮忙。 问题答案: 要在日期上进行文本搜索,您必须将日期转换为文本。 如果您为要查找的内容计算开始和结束日期并获得它们之间的所有内容,则效率会更高。这样,它可以作为数值比较而不是文本模式匹配来完成,并且如果存在索引,则可以利用索引:

  • 问题内容: 我正在尝试创建一个将在每个圣诞节执行特定程序的工作。这是我走了多远: 但是我似乎找不到一种简单的方法来将时间间隔更改为每年一次,并且总体上对如何解决这个问题感到很困惑,任何帮助都非常感谢 问题答案: 你想要类似的东西 该作业将在2012年圣诞节的午夜首次运行,此后每12个月运行一次。

  • 问题内容: 我正在使用和。我以前在sql中使用过正则表达式,现在是我第一次在HQL中使用它。 这是我的hql,当我不带功能运行它时,它按预期运行。但是我不能用表达式执行它。 它说.. 嵌套的异常是org.hibernate.hql.ast.QuerySyntaxException:意外的AST节点:(靠近第1行,第66列..... 请帮助,如何在hibernate本机查询中使用?或其他替代方法。

  • 问题内容: 我对Oracle SQL查询并不十分了解,因此在删除表中的某些行时遇到了一个问题,该行必须满足一个约束,该约束包括另一个(联接)表的字段。换句话说,我想编写一个查询来删除包括JOIN的行。 在我的情况下,我有一个表和另一个连接在字段上的表。我想从大于或等于200的行中删除行,并且它们引用的产品具有名称“ Mark”(名称是“产品”中的一个字段)。 我想首先被告知Oracle中的Dele