当前位置:网站首页>Oracle 11g uses ords+pljson to implement JSON_ Table effect
Oracle 11g uses ords+pljson to implement JSON_ Table effect
2022-07-02 07:11:00 【Virtuous time】
Oracle stay 12.1 Introduced the right json Support for , You can use sql To query json The value of each node of the field , about 11G Version of , for example EBS Environmental Science , It is not convenient to upgrade to 12C, Open source software can be used pljson To achieve , This article uses ORDS + pljson To develop a post Sample request , Receive order data .
Involving software components
ORDS 20.2
pljson 3.5.2
Oracle dbms 11GR2
Oracle apex 20.1
json Data source instance
The following paragraph is to deal with json, It is a multi-level organization , Including order header information and two order lines
{
"PONumber": 1608,
"Requestor": "Alexis Bull",
"CostCenter": "A50",
"Address": {
"street": "200 Sporting Green",
"city": "South San Francisco",
"state": "CA",
"zipCode": 99236,
"country": "United States of America"
},
"LineItems": [
{
"ItemNumber": 1,
"Part": {
"Description": "One Magic Christmas",
"UnitPrice": 19.95,
"UPCCode": 1313109289
},
"Quantity": 9.0
},
{
"ItemNumber": 2,
"Part": {
"Description": "Lethal Weapon",
"UnitPrice": 19.95,
"UPCCode": 8539162892
},
"Quantity": 5.0
}
]
}
Data source reference document
Technical realization
Above Oracle In official documents , Used json_table function , The sum of this function 11G Of xmltable The functional grammar style is very similar , This is 12C Then there is a new function , For processing json String is very convenient , But for 12.1 The previous version does not have this function ,Oracle Always slow down , stay 12C Before, everyone was right about json The demand is relatively strong , So there are open source tools pljson, This plug-in is essentially right Oracle Some applications of sets .
But open source is not as easy to use as native ones implemented from the bottom , For example, there is a query function such as the following code :
select *
from table(
pljson_table.json_table(
'{"data": { "name": "name 3", "description": "blah blah...", "type": "text", "created_time": "2015-12-21T19:23:29+0000", "shares": { "count": 100 }, "extra": null, "maps" : [ true, true, false ] } }',
pljson_varray('data.name', 'data.extra', 'data.maps', 'data.shares.count', 'data.missing'),
pljson_varray('name', 'extra', 'map', 'count', 'whatelse'))
)
As a sql Script in sql There is no problem when running in the engine , But in pl/sql An error will be reported under the engine ORA-22905 Cannot access rows from non nested table entries , The essence is to use table I need to be in pl/sql Block to declare table What type is it inside . however pljson_table.json_table The return value of anydataset, This Oracle ANYDATASET type There is another way to play , Don't study how to realize in pl/sql This is used inside . Change your mind , We can encapsulate the above query into a view , View is used sql engine , And then in pl/sql Just query this view .
Official code
Essentially, we want to achieve the following effects , The following code is from Oracle official ORDS file .
Declare
L_PO BLOB;
Begin
L_PO := :body;
INSERT INTO PurchaseOrder
SELECT * FROM json_table(L_PO FORMAT JSON, '$'
COLUMNS (
PONo Number PATH '$.PONumber',
Requestor VARCHAR2 PATH '$.Requestor',
CostCenter VARCHAR2 PATH '$.CostCenter',
AddressStreet VARCHAR2 PATH '$.Address.street',
AddressCity VARCHAR2 PATH '$.Address.city',
AddressState VARCHAR2 PATH '$.Address.state',
AddressZip VARCHAR2 PATH '$.Address.zipCode',
AddressCountry VARCHAR2 PATH '$.Address.country'));
INSERT INTO LineItem
SELECT * FROM json_table(L_PO FORMAT JSON, '$'
COLUMNS (
PONo Number PATH '$.PONumber',
NESTED PATH '$.LineItems[*]'
COLUMNS (
ItemNumber Number PATH '$.ItemNumber',
PartDescription VARCHAR2 PATH '$.Part.Description',
PartUnitPrice Number PATH '$.Part.UnitPrice',
PartUPCCode Number PATH '$.Part.UPCCode',
Quantity Number PATH '$.Quantity')));
commit;
end;
json_table(L_PO FORMAT JSON It's powerful , A lot of things have been achieved at one time ,blob To clob Transformation , Definition of set .
Therefore, we need to realize it by ourselves blob To clob transformation , because pljson The input parameter received must be clob type .
Table structure
The table structure is as follows :
-- receive POST Come over to the table of raw data
-- Create table
create table CUX_APEX_JSON_CLOB_DATA
(
request_id NUMBER not null,
json_lob CLOB,
creation_date DATE default SYSDATE
);
-- Create/Recreate indexes
create unique index CUX_APEX_JSON_CLOB_DATA_U1 on CUX_APEX_JSON_CLOB_DATA (REQUEST_ID);
-- Sequence
create sequence CUX_APEX_JSON_CLOB_DATA_S;
-- Create table Order header table
create table PURCHASEORDER
(
pono NUMBER(5) not null,
requestor VARCHAR2(50),
costcenter VARCHAR2(5),
addressstreet VARCHAR2(50),
addresscity VARCHAR2(50),
addressstate VARCHAR2(2),
addresszip VARCHAR2(10),
addresscountry VARCHAR2(50),
request_id NUMBER not null
);
-- Create/Recreate primary, unique and foreign key constraints
alter table PURCHASEORDER
add primary key (PONO)
;
-- Create table Order line table
create table LINEITEM
(
pono NUMBER(5) not null,
itemnumber NUMBER(10) not null,
partdescription VARCHAR2(50),
partunitprice NUMBER(10),
partupccode NUMBER(10),
quantity NUMBER(10),
qequest_id NUMBER not null
);
-- Create/Recreate primary, unique and foreign key constraints
alter table LINEITEM
add primary key (PONO, ITEMNUMBER);
bloc_to_clob Conversion function
CREATE OR REPLACE FUNCTION blob_to_clob(blob_in IN BLOB) RETURN CLOB AS
v_clob CLOB;
v_varchar VARCHAR2(32767);
v_start PLS_INTEGER := 1;
v_buffer PLS_INTEGER := 32767;
BEGIN
DBMS_LOB.CREATETEMPORARY(v_clob, TRUE);
FOR i IN 1 .. CEIL(DBMS_LOB.GETLENGTH(blob_in) / v_buffer) LOOP
v_varchar := UTL_RAW.CAST_TO_VARCHAR2(DBMS_LOB.SUBSTR(blob_in,
v_buffer,
v_start));
DBMS_LOB.WRITEAPPEND(v_clob, LENGTH(v_varchar), v_varchar);
--DBMS_OUTPUT.PUT_LINE(v_varchar);
v_start := v_start + v_buffer;
END LOOP;
RETURN v_clob;
END blob_to_clob;
View
-------------------- We need to pay attention to , View select Fields must be capitalized ----------------------------------
-- Header table view
CREATE OR REPLACE VIEW DEMO_HEADER_V AS
SELECT js."PONO",
js."REQUESTOR",
js."COSTCENTER",
js."ADDRESSSTREET",
js."ADDRESSCITY",
js."ADDRESSSTATE",
js."ADDRESSZIP",
js."ADDRESSCOUNTRY",
tab.request_id
FROM cux_apex_json_clob_data tab,
TABLE(pljson_table.json_table(tab.json_lob,
pljson_varray('PONumber',
'Requestor',
'CostCenter',
'Address.street',
'Address.city',
'Address.state',
'Address.zipCode',
'Address.country'),
pljson_varray('pono',
'requestor',
'costcenter',
'addressstreet',
'addresscity',
'addressstate',
'addresszip',
'addresscountry'))) js;
-- Row table view
CREATE OR REPLACE VIEW DEMO_LINE_V AS
SELECT js."PONO",
js."ITEMNUMBER",
js."PARTDESCRIPTION",
js."PARTUNITPRICE",
js."PARTUPCCODE",
js."QUANTITY",
pljtt.request_id
FROM cux_apex_json_clob_data pljtt,
TABLE(pljson_table.json_table(pljtt.json_lob,
pljson_varray('PONumber',
'LineItems[*].ItemNumber',
'LineItems[*].Part.Description',
'LineItems[*].Part.UnitPrice',
'LineItems[*].Part.UPCCode',
'LineItems[*].Quantity'),
pljson_varray('pono',
'itemnumber',
'partdescription',
'partunitprice',
'partupccode',
'quantity'),
table_mode => 'nested')) js;
pl/sql Code
CREATE OR REPLACE PACKAGE cux_apex_json_demo_pkg IS
PROCEDURE create_order(p_body IN BLOB);
END cux_apex_json_demo_pkg;
/
CREATE OR REPLACE PACKAGE BODY cux_apex_json_demo_pkg IS
--******************************************************************************
-- FUNCTION get_tax_rate
--
-- p_body POST Please come here BLOB data
--
-- Public. demo demonstration , obtain POST Over here json data , Put it in storage
--
--******************************************************************************
PROCEDURE create_order(p_body IN BLOB)
IS
c_body CLOB := blob_to_clob(p_body);
l_request_id NUMBER := cux_apex_json_clob_data_s.nextval;
BEGIN
INSERT INTO cux_apex_json_clob_data
VALUES
(l_request_id, c_body, SYSDATE);
plog.debug(l_request_id || '-insert cux_apex_json_clob_data rows:' || SQL%ROWCOUNT);
INSERT INTO PurchaseOrder
SELECT *
FROM demo_header_v
WHERE request_id = l_request_id;
plog.debug(l_request_id || '-insert PurchaseOrder rows:' || SQL%ROWCOUNT);
INSERT INTO LineItem
SELECT *
FROM demo_line_v
WHERE request_id = l_request_id;
plog.debug(l_request_id || '-insert LineItem rows:' || SQL%ROWCOUNT);
COMMIT;
EXCEPTION
WHEN OTHERS THEN
plog.full_error_backtrace;
RAISE;
END create_order;
BEGIN
NULL;
END cux_apex_json_demo_pkg;
/
Package to ORDS in
BEGIN
ORDS.ENABLE_SCHEMA(
p_enabled => TRUE,
p_schema => 'CUX_APEX',
p_url_mapping_type => 'BASE_PATH',
p_url_mapping_pattern => 'CUX_APEX',
p_auto_rest_auth => FALSE);
ORDS.DEFINE_MODULE(
p_module_name => 'demo',
p_base_path => '/demo/',
p_items_per_page => 25,
p_status => 'PUBLISHED',
p_comments => 'json Multiline test ');
ORDS.DEFINE_TEMPLATE(
p_module_name => 'demo',
p_pattern => 'test',
p_priority => 0,
p_etag_type => 'HASH',
p_etag_query => NULL,
p_comments => NULL);
ORDS.DEFINE_HANDLER(
p_module_name => 'demo',
p_pattern => 'test',
p_method => 'POST',
p_source_type => 'plsql/block',
p_items_per_page => 0,
p_mimes_allowed => '',
p_comments => NULL,
p_source =>
'BEGIN cux_apex_json_demo_pkg.create_order(:BODY); END; ');
COMMIT;
END;
stay aepx The following effects are defined in :
Additional updates
The above example requires json Data warehousing , In fact, dynamic sql Words , Can be json Pass in as a binding variable , This avoids inserting redundant data , But the original transmission will be lost json data .
--json Content
{
"DATA":
[{
"storeId":"1","supplierId":"111","takeCost":"1.00","takeDate":"20191112"},
{
"storeId":"2","supplierId":"2","takeCost":"200.00","takeDate":"20191114"},
{
"storeId":"2","supplierId":"3","takeCost":"100.00","takeDate":"20191111"}]
}
-- dynamic sql
execute immediate q'{ insert into supp_cost_t(storeid, supplierid, takecost, takedate) select b.storeid, b.supplierId, b.takeCost, b.takeDate from table(pljson_table.json_table(:1, pljson_varray('DATA[*].storeId', 'DATA[*].supplierId', 'DATA[*].takeCost', 'DATA[*].takeDate'), pljson_varray('storeId', 'supplierId', 'takeCost', 'takeDate'), table_mode => 'nested')) b}'
using json_CLOB;
Reference blog :
https://darkathena.blog.csdn.net/article/details/120644329?spm=1001.2014.3001.5502
边栏推荐
- 数仓模型事实表模型设计
- Sqli-labs customs clearance (less6-less14)
- JS delete the last bit of the string
- SQLI-LABS通关(less2-less5)
- php中在二维数组中根据值返回对应的键值
- Atcoder beginer contest 253 F - operations on a matrix / / tree array
- SQL注入闭合判断
- [daily question] - Huawei machine test 01
- oracle-外币记账时总账余额表gl_balance变化(上)
- sqli-labs通关汇总-page2
猜你喜欢
Only the background of famous universities and factories can programmers have a way out? Netizen: two, big factory background is OK
MapReduce concepts and cases (Shang Silicon Valley Learning Notes)
Principle analysis of spark
In depth study of JVM bottom layer (IV): class file structure
Yolov5 practice: teach object detection by hand
UEditor . Net version arbitrary file upload vulnerability recurrence
Ingress Controller 0.47.0的Yaml文件
Basic knowledge of software testing
Take you to master the formatter of visual studio code
Oracle apex Ajax process + dy verification
随机推荐
RMAN增量恢复示例(1)-不带未备份的归档日志
Oracle 11g sysaux table space full processing and the difference between move and shrink
PM2 simple use and daemon
JS divides an array into groups of three
ORACLE 11G利用 ORDS+pljson来实现json_table 效果
微信小程序基础
Go package name
php中时间戳转换为毫秒以及格式化时间
[leetcode question brushing day 35] 1060 Missing element in ordered array, 1901 Find the peak element, 1380 Lucky number in matrix
The table component specifies the concatenation parallel method
php中计算树状结构数据中的合计
Sqli-labs customs clearance (less1)
2021-07-17C#/CAD二次开发创建圆(5)
js判断数组中对象是否存在某个值
Oracle apex 21.2 installation and one click deployment
js创建一个自定义json数组
Explanation and application of annotation and reflection
Recursion (maze problem, Queen 8 problem)
JS delete the last bit of the string
oracle EBS标准表的后缀解释说明