1

我在集合中有一些数据,我想将其作为响应正文中的结果集发送。

是否可以将关联数组解析为 JSON,然后将其作为结果集发送?

4

3 回答 3

1

根据要求,让我向您展示如何使用嵌入在类型中的集合来创建 json 并通过 Web REST 服务交付它

假设我在表中有员工的数据,我想通过使用 JSON 的 Web 服务检索它们。在这种情况下,我使用 ORDS、APEX 5.1.4 和 Oracle 12c

1.此过程使用 APEX_JSON 检索 JSON 格式的信息。我认为 APEX_JSON 非常适合 Oracle 12c 中的 JSON 生成,因为在 12c 中有很多与 JSON 相关的错误。

CREATE OR REPLACE PROCEDURE get_emp_json (p_empno IN emp.empno%TYPE DEFAULT NULL) AS
  l_cursor SYS_REFCURSOR;
BEGIN
  
  OPEN l_cursor FOR
    SELECT e.empno AS "empno",
           e.ename AS "employee_name",
           e.job AS "job",
           e.mgr AS "mgr",
           TO_CHAR(e.hiredate,'YYYY-MM-DD') AS "hiredate",
           e.sal AS "sal",
           e.comm  AS "comm",
           e.deptno AS "deptno"
    FROM   emp e
    WHERE  e.empno = DECODE(p_empno, NULL, e.empno, p_empno);

  APEX_JSON.open_object;
  APEX_JSON.write('employees', l_cursor);
  APEX_JSON.close_object;
END;
/

2.构建 ORDS REST 模块(在您自己的架构中)

BEGIN
  ORDS.define_module(
    p_module_name    => 'rest-v4',
    p_base_path      => 'rest-v4/',
    p_items_per_page => 0);
  
  ORDS.define_template(
   p_module_name    => 'rest-v4',
   p_pattern        => 'employees/');

  ORDS.define_handler(
    p_module_name    => 'rest-v4',
    p_pattern        => 'employees/',
    p_method         => 'GET',
    p_source_type    => ORDS.source_type_plsql,
    p_source         => 'BEGIN get_emp_json; END;',
    p_items_per_page => 0);
    
  ORDS.define_template(
   p_module_name    => 'rest-v4',
   p_pattern        => 'employees/:empno');

  ORDS.define_handler(
    p_module_name    => 'rest-v4',
    p_pattern        => 'employees/:empno',
    p_method         => 'GET',
    p_source_type    => ORDS.source_type_plsql,
    p_source         => 'BEGIN get_emp_json(:empno); END;',
    p_items_per_page => 0);
    
  COMMIT;
END;
/

3.调用REST WEB SERVICE

http://yourhost:yourport/ords/hr/rest-v4/employees/

结论

ORDS 是一个很棒的工具,可以使用 REST 从数据库中检索 JSON 格式的数据来创建 Web 服务。根据您自己的需要进行调整。通常,集合可以从表或类型派生。在我的示例中,我使用 SYS_REFCURSOR 对象来检索 JSON 数据。

以下文章提供了很好的示例和分步指南

https://oracle-base.com/articles/misc/oracle-rest-data-services-ords-create-basic-rest-web-services-using-plsql#create-get-web-services

https://oracle-base.com/articles/misc/oracle-rest-data-services-ords-restful-web-services-handling-complex-json-payloads

于 2020-07-15T14:29:22.410 回答
0

@RobertoHernandez 提供了 ORDS 服务的基本概述,这不是我正在寻找的,但谢谢!

  1. 填充集合并创建 JSON 对象的函数:
CREATE OR REPLACE FUNCTION f_get_data RETURN CLOB
AS
    cst_key CONSTANT VARCHAR(32) := 'KEY';
    cst_value CONSTANT VARCHAR(32) := 'VALUE';

    TYPE r_summary IS RECORD (
        key   VARCHAR2(255),
        value NUMBER
    ); 
    
    TYPE t_summary IS TABLE OF r_summary INDEX BY BINARY_INTEGER;
    
    r_s     r_summary;
    tab_s t_summary;

    json_clob CLOB;
 
    i INTEGER;   
BEGIN
    -- insert some dummy data to the collection
    FOR i IN 1..10 LOOP
        r_s.key := dbms_random.string('A', 10);
        r_s.value := ROUND(dbms_random.value(1,10), 2);
        
        tab_s(tab_s.COUNT + 1) := r_s;
    END LOOP;
    
    -- write data to a JSON object
    APEX_JSON.initialize_clob_output;
    APEX_JSON.open_object;
    
    APEX_JSON.open_array('data');
   
    IF tab_s.COUNT > 0 THEN
        FOR i IN tab_s.FIRST..tab_s.LAST LOOP
            IF tab_s.EXISTS(i) THEN
                APEX_JSON.open_object;
                APEX_JSON.write(cst_key, tab_s(i).key);
                APEX_JSON.write(cst_value, tab_s(i).value);
                APEX_JSON.close_object;
            END IF;
        END LOOP;
    END IF;
    
    APEX_JSON.close_all;
    
    json_clob := APEX_JSON.get_clob_output;
    APEX_JSON.free_output;
   
    RETURN json_clob;
END;
  1. 将 Web 服务创建为:
BEGIN
  ORDS.DEFINE_MODULE(
      p_module_name    => 'test',
      p_base_path      => '/data/',
      p_items_per_page =>  25,
      p_status         => 'PUBLISHED',
      p_comments       => NULL);  
  
  ORDS.DEFINE_TEMPLATE(
      p_module_name    => 'test',
      p_pattern        => 'all',
      p_priority       => 0,
      p_etag_type      => 'HASH',
      p_etag_query     => NULL,
      p_comments       => NULL);
  ORDS.DEFINE_HANDLER(
      p_module_name    => 'test',
      p_pattern        => 'all',
      p_method         => 'GET',
      p_source_type    => 'resource/lob',
      p_items_per_page =>  25,
      p_mimes_allowed  => '',
      p_comments       => NULL,
      p_source         => 
'SELECT
    ''application/json'',
    f_get_data
FROM
    sys.dual'
      );


  COMMIT; 
END;
  1. 最后调用 ORDS:
http://<host>:<port>/ords/<db>/<schema>/data/all/

有关更多详细信息,请阅读以下文章,它给了我这个想法(@thatjeffsmith 的信条):

https://www.thatjeffsmith.com/archive/2017/09/ords-returning-raw-json/

于 2020-07-20T08:37:41.110 回答
0

当您希望将 JSON 数组作为输出参数返回时,这种返回 a 的技术refcursor也适用。autorest

您必须在模式或包级别声明记录和类型才能使其工作。

FUNCTION f_get_data
    RETURN SYS_REFCURSOR AS
    cst_key     CONSTANT VARCHAR(32) := 'KEY';
    cst_value   CONSTANT VARCHAR(32) := 'VALUE';


    r_s                  r_summary;
    tab_s                t_summary;

    json_clob            SYS_REFCURSOR;

    i                    INTEGER;
BEGIN
    -- insert some dummy data to the collection
    FOR i IN 1 .. 10
    LOOP
        r_s.key := DBMS_RANDOM.string('A', 10);
        r_s.VALUE := ROUND(DBMS_RANDOM.VALUE(1, 10), 2);

        tab_s(tab_s.COUNT + 1) := r_s;
    END LOOP;

    OPEN json_clob FOR SELECT * FROM TABLE(tab_s);

    RETURN json_clob;
END;
于 2020-07-29T17:11:48.457 回答