Sql 如何使ORDS查询返回不带引号的JSON_对象?
我试图构建一个JSON,作为在Oracle数据库XE 18c上使用ORDS进行HTTP GET的结果返回。使用JSON_对象和类似的函数,SELECT似乎总是用引号包围生成的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
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