Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/oracle/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql 如何使ORDS查询返回不带引号的JSON_对象?_Sql_Oracle_Rest_Oracle Ords - Fatal编程技术网

Sql 如何使ORDS查询返回不带引号的JSON_对象?

Sql 如何使ORDS查询返回不带引号的JSON_对象?,sql,oracle,rest,oracle-ords,Sql,Oracle,Rest,Oracle Ords,我试图构建一个JSON,作为在Oracle数据库XE 18c上使用ORDS进行HTTP GET的结果返回。使用JSON_对象和类似的函数,SELECT似乎总是用引号包围生成的JSON,并在对象中转义引号。例如: CREATE TABLE test_cases ( team VARCHAR2(3), response_time NUMBER ); INSERT INTO test_cases (team, response_time) VALUES ('foo', 1); INS

我试图构建一个JSON,作为在Oracle数据库XE 18c上使用ORDS进行HTTP GET的结果返回。使用JSON_对象和类似的函数,SELECT似乎总是用引号包围生成的JSON,并在对象中转义引号。例如:

CREATE TABLE test_cases (
    team VARCHAR2(3),
    response_time NUMBER
);

INSERT INTO test_cases (team, response_time) VALUES ('foo', 1);
INSERT INTO test_cases (team, response_time) VALUES ('foo', 2);
INSERT INTO test_cases (team, response_time) VALUES ('foo', 5);
INSERT INTO test_cases (team, response_time) VALUES ('bar', 5);
INSERT INTO test_cases (team, response_time) VALUES ('bar', 7);
INSERT INTO test_cases (team, response_time) VALUES ('bar', 9);
COMMIT;

BEGIN
  ORDS.define_module(
    p_module_name    => 'rest',
    p_base_path      => 'rest/',
    p_items_per_page => 0
  );

  ORDS.define_template(
    p_module_name    => 'rest',
    p_pattern        => 'stats/'
  );

  ORDS.define_handler(
    p_module_name    => 'rest',
    p_pattern        => 'stats/',
    p_method         => 'GET',
    p_source_type    => ORDS.source_type_query_one_row,
    p_source         => '
SELECT JSON_OBJECTAGG (
    KEY t.team VALUE AVG(t.response_time)
)
AS averages
FROM test_cases t 
GROUP BY t.team 
                        ',
    p_items_per_page => 0
  );

  COMMIT;
END;
/
请求资源会得到以下结果:

$ curl -i -H "Content-Type: application/json" -X GET "http://localhost:8080/ords/rest/stats/"
HTTP/1.1 200 OK
Content-Type: application/json
{"averages":"{\"foo\":2.66666666666666666666666666666666666667,\"bar\":7}"}
其中引用了JSON值“averages”。这种行为似乎是JSON_对象特有的,因为使用相同ORDS参数的其他SELECT调用不会在结果中添加引号


在将JSON_对象的输出构建到SELECT的结果中之前,是否有一种方法可以对其进行字符串化?

由于您自己生成JSON,因此需要将源类型更改为媒体资源。然后在查询中,第一列将是mime类型,以便浏览器知道如何处理传入的二进制数据

试试这个-

BEGIN
  ORDS.DEFINE_HANDLER(
      p_module_name    => 'rest',
      p_pattern        => 'stats/',
      p_method         => 'GET',
      p_source_type    => 'resource/lob',
      p_items_per_page =>  0,
      p_mimes_allowed  => '',
      p_comments       => NULL,
      p_source         => 
'SELECT ''application/json'', JSON_OBJECTAGG (
    KEY t.team VALUE AVG(t.response_time)
)
AS averages
FROM test_cases t 
GROUP BY t.team '
      );

  COMMIT; 
END;
/
然后我在我的浏览器中进行GET调用-

现在,假设您也有一些常规数据,但其中只有一列是存储在DB中或由DB生成的JSON—您希望ORDS将常规数据JSON化,而不是已经是JSON的数据

有一种方法可以让你吃蛋糕,也可以用银勺子

BEGIN
  ORDS.DEFINE_HANDLER(
      p_module_name    => 'rest',
      p_pattern        => 'stats/',
      p_method         => 'GET',
      p_source_type    => 'json/collection',
      p_items_per_page =>  0,
      p_mimes_allowed  => '',
      p_comments       => NULL,
      p_source         => 
'SELECT JSON_OBJECTAGG (
    KEY t.team VALUE AVG(t.response_time)
)
"{}jsons"
FROM test_cases t 
GROUP BY t.team '
      );

  COMMIT; 
END;
/
对于JSON数据,请添加此列别名

"{}jsons"
现在运行这个看起来是这样的-


由于您自己生成JSON,因此需要将源类型更改为媒体资源。然后在查询中,第一列将是mime类型,以便浏览器知道如何处理传入的二进制数据

试试这个-

BEGIN
  ORDS.DEFINE_HANDLER(
      p_module_name    => 'rest',
      p_pattern        => 'stats/',
      p_method         => 'GET',
      p_source_type    => 'resource/lob',
      p_items_per_page =>  0,
      p_mimes_allowed  => '',
      p_comments       => NULL,
      p_source         => 
'SELECT ''application/json'', JSON_OBJECTAGG (
    KEY t.team VALUE AVG(t.response_time)
)
AS averages
FROM test_cases t 
GROUP BY t.team '
      );

  COMMIT; 
END;
/
然后我在我的浏览器中进行GET调用-

现在,假设您也有一些常规数据,但其中只有一列是存储在DB中或由DB生成的JSON—您希望ORDS将常规数据JSON化,而不是已经是JSON的数据

有一种方法可以让你吃蛋糕,也可以用银勺子

BEGIN
  ORDS.DEFINE_HANDLER(
      p_module_name    => 'rest',
      p_pattern        => 'stats/',
      p_method         => 'GET',
      p_source_type    => 'json/collection',
      p_items_per_page =>  0,
      p_mimes_allowed  => '',
      p_comments       => NULL,
      p_source         => 
'SELECT JSON_OBJECTAGG (
    KEY t.team VALUE AVG(t.response_time)
)
"{}jsons"
FROM test_cases t 
GROUP BY t.team '
      );

  COMMIT; 
END;
/
对于JSON数据,请添加此列别名

"{}jsons"
现在运行这个看起来是这样的-


您是否尝试过使用
键t.team VALUE AVG(t.response\u time)返回clob格式的json
?我没有尝试过,但它给出了相同的结果。如果我理解正确,这些修饰符将应用于该值(在本例中为AVG(t.response_time))。我的问题是,整个JSON_OBJECTAGG结果在被指定为结果JSON中的“平均值”之前被引用。您是否尝试过
KEY t.team value AVG(t.response_time)返回clob格式JSON
?我没有,但它给出了相同的结果。如果我理解正确,这些修饰符将应用于该值(在本例中为AVG(t.response_time))。我的问题是,整个JSON_OBJECTAGG结果在被指定为结果JSON中的“平均值”之前被引用。使用您的答案和JSON函数(JSON_object,JSON_arrayagg),我能够通过消除光标表达式来解决分页问题。谢谢太棒了,谢谢分享@foobarbazu使用您的答案和JSON函数(JSON_对象,JSON_arrayagg),我能够通过消除游标表达式来解决分页问题。谢谢太棒了,谢谢分享@foobarbaz