oracle11g解码JSON blob
我很难将从ORDS接收到的JSON负载解码成blob,所以我决定编写自己的函数。我的表格如下:oracle11g解码JSON blob,json,oracle,oracle11g,Json,Oracle,Oracle11g,我很难将从ORDS接收到的JSON负载解码成blob,所以我决定编写自己的函数。我的表格如下: CREATE TABLE EDI_TRANSIT_UPDATE ( SEQ_NO NUMBER, CREATED_DATE DATE, CREATED_BY VARCHAR2(20 BYTE), LAST_UPDATE_DATE DATE, LAST_UPDATE_BY VARCHAR2(20 BYTE), PROCESSE
CREATE TABLE EDI_TRANSIT_UPDATE
(
SEQ_NO NUMBER,
CREATED_DATE DATE,
CREATED_BY VARCHAR2(20 BYTE),
LAST_UPDATE_DATE DATE,
LAST_UPDATE_BY VARCHAR2(20 BYTE),
PROCESSED VARCHAR2(1 BYTE) DEFAULT 'N',
CLOB BLOB
);
{ "TRAIN_NO": "B1Z1002153250819",
"CONSIGNMENT_NUMBER": "8094777054",
"TRAIN_ORIGIN_NAME": "BELLVILLE",
"TRAIN_ORIGIN_DATE": "2019-08-25T00:00:00",
"CurrentStationTime": "2019-08-25T22:55:19",
"CurrentStationPlannedTime": "2019-08-25T20:52:00",
"TrainLONG": 19.66555008,
"TrainLAT": -33.4827,
"CurrentStationDelay": 123,
"TrainETD": "2019-08-25T15:30:00",
"TrainETA": "2019-08-26T04:40:00",
"TrainNewETA": "2019-08-26T06:43:00"
}
然后我创建了一个JSON解码函数来返回字段的值
CREATE OR REPLACE FUNCTION GET_JSON_FIELD (field varchar2, blob_in IN BLOB,vfield_no number, num_var varchar2,num_numerics number)
RETURN VARCHAR2 AS
s number;
e number;
len number;
field_len number;
w_ret_field varchar2(100);
/*
field --> the JSON field that you looking for
blob_in the blob containing the JSON payload
vfield_no is the numeric number or order of the field
num_var is c or n (c for character and n for numeric
num_numerics is for the number of numeric fields before the character field you looking for
*/
BEGIN
if num_var='c' then -- character fields i.e. fields surrounded with "
field_len:=length(field)+3;
select instr( UTL_RAW.CAST_TO_VARCHAR2( blob_in ),field,1,1)+field_len into s from dual; -- start position
select instr( UTL_RAW.CAST_TO_VARCHAR2( blob_in ),'",',1,vfield_no-num_numerics) into e from dual; -- end position
if e = 0 then --this if is for the last field
select instr( UTL_RAW.CAST_TO_VARCHAR2( blob_in ),'"}',1,1) into e from dual; -- end position
end if;
len:=e-s; -- length of the field
select UTL_RAW.CAST_TO_VARCHAR2(DBMS_LOB.SUBSTR(blob_in, len,s)) into w_ret_field from dual; -- the varchar selected
end if;
if num_var='n' then -- numeric fields i.e. fields not surrounded with "
field_len:=length(field)+2;
select instr( UTL_RAW.CAST_TO_VARCHAR2( blob_in ),field,1,1)+field_len into s from dual; -- start position
select instr( UTL_RAW.CAST_TO_VARCHAR2( blob_in ),',',1,vfield_no) into e from dual; -- end position
if e = 0 then --this if is for the last field
select instr( UTL_RAW.CAST_TO_VARCHAR2( blob_in ),',}',1,1) into e from dual; -- end position
end if;
len:=e-s; -- length of the field
select UTL_RAW.CAST_TO_VARCHAR2(DBMS_LOB.SUBSTR(blob_in, len,s)) into w_ret_field from dual; -- the varchar selected
end if;
RETURN w_ret_field;
END GET_JSON_FIELD;
/
然后我通过传入字段名来调用它,如果它返回一个字符或数字,则是字段的编号,如果它是字符字段,则是它前面的数字字段的编号:
CREATE OR REPLACE PROCEDURE process_transit_data1 IS
w_TRAIN_NO VARCHAR2(100);
w_CONSIGNMENT_NUMBER VARCHAR2(100);
w_TRAIN_ORIGIN_NAME VARCHAR2(100);
w_TRAIN_ORIGIN_DATE VARCHAR2(100);
w_CURRENTSTATIONTIME VARCHAR2(100);
w_CURRENTSTATIONPLANNEDTIME VARCHAR2(100);
w_TRAINLONG VARCHAR2(100);
w_TRAINLAT VARCHAR2(100);
w_CURRENTSTATIONDELAY VARCHAR2(100);
w_TRAINETD VARCHAR2(100);
w_TRAINETA VARCHAR2(100);
w_TRAINNEWETA VARCHAR2(100);
s number;
e number;
len number;
loopcount number;
vfield number;
nfield number;
v_blob blob;
CURSOR ords
IS
SELECT seq_no from EDI_TRANSIT_UPDATE where processed = 'N' order by created_date;
BEGIN
for processloop in ords loop
SELECT clob into v_blob from EDI_TRANSIT_UPDATE where seq_no=processloop.seq_no;
trace('TRANSIT','seq_no to process: '||processloop.seq_no);
vfield:=1;
nfield:= 1;
BEGIN
w_TRAIN_NO :=GET_JSON_FIELD('TRAIN_NO', v_blob, vfield,'c',0 ); -- 'c' is character, 0 is 0 numerics fields before
vfield:=vfield+1;
EXCEPTION
WHEN OTHERS THEN
w_TRAIN_NO :=NULL;
END;
BEGIN
w_CONSIGNMENT_NUMBER :=GET_JSON_FIELD('CONSIGNMENT_NUMBER', v_blob, vfield,'c',0 );
vfield:=vfield+1;
EXCEPTION
WHEN OTHERS THEN
w_CONSIGNMENT_NUMBER :=NULL;
END;
BEGIN
w_TRAIN_ORIGIN_NAME :=GET_JSON_FIELD('TRAIN_ORIGIN_NAME', v_blob, vfield,'c',0 );
vfield:=vfield+1;
EXCEPTION
WHEN OTHERS THEN
w_TRAIN_ORIGIN_NAME :=NULL;
END;
BEGIN
w_TRAIN_ORIGIN_DATE :=GET_JSON_FIELD('TRAIN_ORIGIN_DATE', v_blob, vfield,'c',0 );
vfield:=vfield+1;
EXCEPTION
WHEN OTHERS THEN
w_TRAIN_ORIGIN_DATE :=NULL;
END;
BEGIN
w_CURRENTSTATIONTIME :=GET_JSON_FIELD('CurrentStationTime', v_blob, vfield,'c',0 );
vfield:=vfield+1;
EXCEPTION
WHEN OTHERS THEN
w_CURRENTSTATIONTIME :=NULL;
END;
BEGIN
w_CURRENTSTATIONPLANNEDTIME :=GET_JSON_FIELD('CurrentStationPlannedTime', v_blob, vfield,'c',0 );
vfield:=vfield+1;
EXCEPTION
WHEN OTHERS THEN
w_CURRENTSTATIONPLANNEDTIME :=NULL;
END;
BEGIN
w_TRAINLONG :=GET_JSON_FIELD('TrainLONG', v_blob, vfield,'n',0 );
vfield:=vfield+1;
EXCEPTION
WHEN OTHERS THEN
w_TRAINLONG :=NULL;
END;
BEGIN
w_TRAINLAT :=GET_JSON_FIELD('TrainLAT', v_blob, vfield,'n',0 );
vfield:=vfield+1;
EXCEPTION
WHEN OTHERS THEN
w_TRAINLAT :=NULL;
END;
BEGIN
w_CURRENTSTATIONDELAY :=GET_JSON_FIELD('CurrentStationDelay', v_blob, vfield,'n',0 ); -- 'n' is for a numeric field i.e no " "
vfield:=vfield+1;
EXCEPTION
WHEN OTHERS THEN
w_CURRENTSTATIONDELAY :=NULL;
END;
BEGIN
w_TRAINETD :=GET_JSON_FIELD('TrainETD', v_blob, vfield,'c',3 ); -- 3 for 3 numeric fields before i.e ended with ' not ",
vfield:=vfield+1;
EXCEPTION
WHEN OTHERS THEN
w_TRAINETD :=NULL;
END;
BEGIN
w_TRAINETA :=GET_JSON_FIELD('TrainETA', v_blob, vfield,'c',3 );
vfield:=vfield+1;
EXCEPTION
WHEN OTHERS THEN
w_TRAINETA :=NULL;
END;
BEGIN
w_TRAINNEWETA :=GET_JSON_FIELD('TrainNewETA', v_blob, vfield,'c',3 );
vfield:=vfield+1;
EXCEPTION
WHEN OTHERS THEN
w_TRAINNEWETA :=NULL;
END;
--insert
trace('TRANSIT','begin insert');
insert into EDI_TRANSIT_DATA (EDI_TRANSIT_UPDATE_SEQ,TRAIN_NO,CONSIGNMENT_NUMBER,TRAIN_ORIGIN_NAME,TRAIN_ORIGIN_DATE,CURRENTSTATIONTIME,CURRENTSTATIONPLANNEDTIME,TrainLONG,TrainLAT,CURRENTSTATIONDELAY,TRAINETD,TRAINETA,TRAINNEWETA )
values (processloop.seq_no,w_TRAIN_NO,w_CONSIGNMENT_NUMBER,w_TRAIN_ORIGIN_NAME,REPLACE(w_TRAIN_ORIGIN_DATE,'T',' '),REPLACE(w_CURRENTSTATIONTIME,'T',' '),REPLACE(w_CURRENTSTATIONPLANNEDTIME,'T',' '),w_TrainLONG,w_TrainLAT,w_CURRENTSTATIONDELAY,REPLACE(w_TRAINETD,'T',' '),REPlACE(w_TRAINETA,'T',' '),REPLACE(w_TRAINNEWETA,'T',' '));
commit;
trace('TRANSIT','end insert');
update EDI_TRANSIT_UPDATE set processed = 'Y' where seq_no = processloop.seq_no; commit;
end loop;
END process_transit_data1;
/
我希望你能从中得到一个想法,因为它适合我。顺便说一下,我的JSON负载如下所示:
CREATE TABLE EDI_TRANSIT_UPDATE
(
SEQ_NO NUMBER,
CREATED_DATE DATE,
CREATED_BY VARCHAR2(20 BYTE),
LAST_UPDATE_DATE DATE,
LAST_UPDATE_BY VARCHAR2(20 BYTE),
PROCESSED VARCHAR2(1 BYTE) DEFAULT 'N',
CLOB BLOB
);
{ "TRAIN_NO": "B1Z1002153250819",
"CONSIGNMENT_NUMBER": "8094777054",
"TRAIN_ORIGIN_NAME": "BELLVILLE",
"TRAIN_ORIGIN_DATE": "2019-08-25T00:00:00",
"CurrentStationTime": "2019-08-25T22:55:19",
"CurrentStationPlannedTime": "2019-08-25T20:52:00",
"TrainLONG": 19.66555008,
"TrainLAT": -33.4827,
"CurrentStationDelay": 123,
"TrainETD": "2019-08-25T15:30:00",
"TrainETA": "2019-08-26T04:40:00",
"TrainNewETA": "2019-08-26T06:43:00"
}
那么,真正的问题是什么?有更好的方法还是更有效的方法?