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
将大JSON文件存储到Oracle数据库中_Oracle_Plsql_Oracle11g_Pljson - Fatal编程技术网

将大JSON文件存储到Oracle数据库中

将大JSON文件存储到Oracle数据库中,oracle,plsql,oracle11g,pljson,Oracle,Plsql,Oracle11g,Pljson,我使用以下脚本从MongoDB中读取数据作为JSON文件 DECLARE l_param_list VARCHAR2(512); l_http_request UTL_HTTP.req; l_http_response UTL_HTTP.resp; l_response_text CLOB; --l_response_text VARCHAR2(32767); l_list json_list; A_id VARCHAR2(100)

我使用以下脚本从MongoDB中读取数据作为JSON文件

DECLARE
  l_param_list     VARCHAR2(512);
 
  l_http_request   UTL_HTTP.req;
  l_http_response  UTL_HTTP.resp;
  l_response_text  CLOB;
  --l_response_text  VARCHAR2(32767);

l_list json_list;
A_id           VARCHAR2(100);
Photo          VARCHAR2(32767);
A_Name         VARCHAR2(100);
Remarks        VARCHAR2(100);
Status         VARCHAR2(100);
UserId         VARCHAR2(100);
A_Date         VARCHAR2(100);
A_Time         VARCHAR2(100);
MSG_status     VARCHAR2(100);
Oracle_Flag    VARCHAR2(100);
acl            VARCHAR2(100);


BEGIN

  -- service's input parameters

  -- preparing Request...
  l_http_request := UTL_HTTP.begin_request('https://api.appery.io/rest/1/db/collections/Photos?where=%7B%22Oracle_Flag%22%3A%22Y%22%7D'
                                          , 'GET'
                                          , 'HTTP/1.1');
 
  -- ...set header's attributes
  UTL_HTTP.set_header(l_http_request, 'X-Appery-Database-Id', '53f2dac5e4b02cca64021dbe');
  --UTL_HTTP.set_header(l_http_request, 'Content-Length', LENGTH(l_param_list));

  -- ...set input parameters
 -- UTL_HTTP.write_text(l_http_request, l_param_list);

  -- get Response and obtain received value
  l_http_response := UTL_HTTP.get_response(l_http_request);

  UTL_HTTP.read_text(l_http_response, l_response_text);

  DBMS_OUTPUT.put_line(l_response_text);
 l_list := json_list(l_response_text);

FOR i IN 1..l_list.count
LOOP
A_id        := json_ext.get_string(json(l_list.get(i)),'_id');
Photo       := json_ext.get_string(json(l_list.get(i)),'Photo');
A_Name      := json_ext.get_string(json(l_list.get(i)),'Name');
Remarks     := json_ext.get_string(json(l_list.get(i)),'Remarks');
Status      := json_ext.get_string(json(l_list.get(i)),'Status');
UserId      := json_ext.get_string(json(l_list.get(i)),'UserId');
A_Date      := json_ext.get_string(json(l_list.get(i)),'Date');
A_Time      := json_ext.get_string(json(l_list.get(i)),'Time');
MSG_status  := json_ext.get_string(json(l_list.get(i)),'MSG_status');
Oracle_Flag := json_ext.get_string(json(l_list.get(i)),'Oracle_Flag');
acl         := json_ext.get_string(json(l_list.get(i)),'acl');


insert into Appery_Photos values(
  A_id,
  Photo,
  A_Name,
  Remarks,
  Status,
  UserId,
  A_Date,
  A_Time,
  MSG_status ,
  Oracle_Flag,
  acl
);
  end loop;

-- finalizing
  UTL_HTTP.end_response(l_http_response);

EXCEPTION 
  WHEN UTL_HTTP.end_of_body 
    THEN UTL_HTTP.end_response(l_http_response);  
END;
/
该脚本可以很好地处理小JSON文件。但是,当文件包含base64文件(照片以base64格式表示)时,脚本将失败并给出错误(未找到字符串结尾)

显然,错误的原因是没有复制整个文件,因此JSON解析器无法找到字符串“]”或“}”的结尾

我尝试使用CLOB和VARCHAR2,最大大小为32767,但这还远远不够

我曾想过解码base64文件,但问题是我需要先读取该文件,然后才能解码该字段

任何建议都将不胜感激

结果 这两个答案都提供了读取大型JSON文件(>32KB)的解决方案,我使用了@Jeffrey Kemp one。然而,作为下一个问题,json_值/字段本身大于32KB,json_ext.get_字符串只返回一个VARCHAR2,这意味着它的最大值限制为32767 byes。因此对于值大于32KB的字段照片,我使用了json_ext.get_json_值以及dbms_lob.createtemporary。整理后的相关脚本如下:

DECLARE
  l_val            json_value;
  l_param_list     VARCHAR2(512);
  l_http_request   UTL_HTTP.req;
  l_http_response  UTL_HTTP.resp;
  l_response_text  CLOB;
  --l_response_text  VARCHAR2(32767);

l_list json_list;
A_id           VARCHAR2(100);
Photo          VARCHAR2(32767);
A_Name         VARCHAR2(100);
Remarks        VARCHAR2(100);
Status         VARCHAR2(100);
UserId         VARCHAR2(100);
A_Date         VARCHAR2(100);
A_Time         VARCHAR2(100);
MSG_status     VARCHAR2(100);
Oracle_Flag    VARCHAR2(100);
acl            VARCHAR2(100);


BEGIN

  -- service's input parameters

  -- preparing Request...
  l_http_request := UTL_HTTP.begin_request('https://api.appery.io/rest/1/db/collections/Photos?where=%7B%22Oracle_Flag%22%3A%22Y%22%7D'
                                          , 'GET'
                                          , 'HTTP/1.1');
 
  -- ...set header's attributes
  UTL_HTTP.set_header(l_http_request, 'X-Appery-Database-Id', '53f2dac5e4b02cca64021dbe');
  --UTL_HTTP.set_header(l_http_request, 'Content-Length', LENGTH(l_param_list));

  -- ...set input parameters
 -- UTL_HTTP.write_text(l_http_request, l_param_list);

  -- get Response and obtain received value
  l_http_response := UTL_HTTP.get_response(l_http_request);
  BEGIN
    LOOP
      UTL_HTTP.read_text(l_http_response, buf);
      l_response_text := l_response_text || buf;
    END LOOP;
  EXCEPTION
  WHEN UTL_HTTP.end_of_body THEN
    NULL;
  END;
  l_list := json_list(l_response_text);


FOR i IN 1..l_list.count
LOOP
A_id        := json_ext.get_string(json(l_list.get(i)),'_id');
l_val := json_ext.get_json_value(json(l_list.get(i)),'Photo');
dbms_lob.createtemporary(Photo, true, 2);
json_value.get_string(l_val, Photo);
A_Name      := json_ext.get_string(json(l_list.get(i)),'Name');
Remarks     := json_ext.get_string(json(l_list.get(i)),'Remarks');
Status      := json_ext.get_string(json(l_list.get(i)),'Status');
UserId      := json_ext.get_string(json(l_list.get(i)),'UserId');
A_Date      := json_ext.get_string(json(l_list.get(i)),'Date');
A_Time      := json_ext.get_string(json(l_list.get(i)),'Time');
MSG_status  := json_ext.get_string(json(l_list.get(i)),'MSG_status');
Oracle_Flag := json_ext.get_string(json(l_list.get(i)),'Oracle_Flag');
acl         := json_ext.get_string(json(l_list.get(i)),'acl');


insert into Appery_Photos values(
  A_id,
  Photo,
  A_Name,
  Remarks,
  Status,
  UserId,
  A_Date,
  A_Time,
  MSG_status ,
  Oracle_Flag,
  acl
);
  end loop;

-- finalizing
  UTL_HTTP.end_response(l_http_response);

EXCEPTION 
  WHEN UTL_HTTP.end_of_body 
    THEN UTL_HTTP.end_response(l_http_response);  
END;
/

但是这里的限制是,它以
VARCHAR2
的形式返回结果(这里有一个隐式转换)

要从web轻松检索大型文本对象,您可能需要


如果出于某种原因,您想坚持使用
UTL\uhttp
,则必须循环逐块读取数据。诸如此类:

BEGIN
  ...
  l_clob           CLOB;
  l_text           VARCHAR2(32767);
BEGIN
  DBMS_LOB.createtemporary(l_clob, FALSE);

  ...
  l_http_request  := UTL_HTTP.begin_request(your_URI);
  l_http_response := UTL_HTTP.get_response(l_http_request);

  -- Loop to read data chunk by chunk up to the end
  BEGIN
    LOOP
      UTL_HTTP.read_text(l_http_response, l_text, 32766);
      DBMS_LOB.writeappend (l_clob, LENGTH(l_text), l_text);
    END LOOP;
  EXCEPTION
    WHEN UTL_HTTP.end_of_body THEN
      UTL_HTTP.end_response(l_http_response);
  END;

请参阅各种示例

您的问题在于调用
UTL\u HTTP.read\u text
。您正在传递CLOB,但read_text只接受VARCHAR2,因此它最多可以返回32k字节

您需要使用VARCHAR2缓冲区在循环中调用它,并将结果连接到CLOB中,例如:

DECLARE
  buf VARCHAR2(32767);
BEGIN
  LOOP
    UTL_HTTP.read_text(l_http_response, buf);
    l_response_text := l_response_text || buf;
  END LOOP;
EXCEPTION
  WHEN UTL_HTTP.end_of_body THEN
    NULL;
END;


您的第二个问题是
json\u ext.get\u string
只返回一个VARCHAR2,这意味着它最多只能返回32767个byes。我浏览了,您可能需要联系其中一位作者,以了解如何使用它来获取CLOB值。

除了“Photo”字段外,这一切正常。字段“Photo”是base64格式>32KB的图像。当前脚本将所有字段正确存储到DB中的列中。但是,值“Photo”不完整。我认为问题源于Photo:=json_ext.get_string(json(l_list.get(I)),'Photo');线路。但是无法找到解决方法。updated-json_ext.get_string似乎只支持VARCHAR2。我在大于32KB的字段中添加了以下内容:l_val:=json_ext.get_json_value(json(l_list.get(I)),'Photo');dbms_lob.createtemporary(照片,真,2);json_value.get_字符串(l_val,照片);它是有效的。