如何使 ORDS 查询 return a JSON_OBJECT 不带引号?
How do I make an ORDS query return a JSON_OBJECT without quotes?
我正在尝试构建一个 JSON 到 return 作为在 Oracle 数据库 XE 18c 上使用 ORDS 的 HTTP GET 的结果。使用 JSON_OBJECT 和类似函数,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}"}
其中引用了 "averages" 的 JSON 值。该行为似乎是 JSON_OBJECT 特有的,因为使用相同 ORDS 参数的其他 SELECT 调用不会在结果中添加引号。
有没有办法在将 JSON_OBJECT 的输出构建到 SELECT 的结果之前对其进行去字符串化?
由于您是自己生成 JSON,因此您想将 SOURCE_TYPE 更改为媒体资源。然后在您的查询中,第一列将是您的 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 -
{
"foo": 2.6666666666666665,
"bar": 7
}
现在,假设您还有一些常规数据,但只有一列 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 到 return 作为在 Oracle 数据库 XE 18c 上使用 ORDS 的 HTTP GET 的结果。使用 JSON_OBJECT 和类似函数,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}"}
其中引用了 "averages" 的 JSON 值。该行为似乎是 JSON_OBJECT 特有的,因为使用相同 ORDS 参数的其他 SELECT 调用不会在结果中添加引号。
有没有办法在将 JSON_OBJECT 的输出构建到 SELECT 的结果之前对其进行去字符串化?
由于您是自己生成 JSON,因此您想将 SOURCE_TYPE 更改为媒体资源。然后在您的查询中,第一列将是您的 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 -
{
"foo": 2.6666666666666665,
"bar": 7
}
现在,假设您还有一些常规数据,但只有一列 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"
运行 现在看起来是这样的 -