如何在pl / sql中将49.000个字符长的json字符串处理为clob

问题描述 投票:0回答:1

我有一个非常长的json-String,包含超过49k个字符,因此不适合放入Clob。我有一个将json-String作为Clob输入的过程。在那里,我想读出所有值并将其插入到表中。如果我将json-String缩小以进行测试,则一切正常。但是正如我所说,json-String的长度超过了49k个字符。

我的程序的头看起来像这样:

PROCEDURE set_FDC_Data(in_json IN CLOB) IS
    v_json          elmos_opt.json;
    v_json_keys     elmos_opt.json_list;
    v_json_else_obj elmos_opt.json;

    v_elseNr VARCHAR(10);
    v_pce    VARCHAR(10);

    v_channel1    elmos_opt.json;
    v_protocolCh1 VARCHAR(10);
    v_portCh1     NUMBER;
    v_deviceIdCh1 NUMBER;
    v_t3Ch1       NUMBER;
    v_t1Ch1       NUMBER;
    v_t2Ch1       NUMBER;
    v_t4Ch1       NUMBER;
    v_t5Ch1       NUMBER;
    v_t6Ch1       NUMBER;
    v_t7Ch1       NUMBER;
    v_t8Ch1       NUMBER;

    v_channel2      elmos_opt.json;
    v_remoteHostCh2 VARCHAR(50);
    v_protocolCh2   VARCHAR(10);
    v_portCh2       NUMBER;
    v_deviceIdCh2   NUMBER;
    v_t3Ch2         NUMBER;
    v_t1Ch2         NUMBER;
    v_t2Ch2         NUMBER;
    v_t4Ch2         NUMBER;
    v_t5Ch2         NUMBER;
    v_t6Ch2         NUMBER;
    v_t7Ch2         NUMBER;
    v_t8Ch2         NUMBER;

    v_channel3    elmos_opt.json;
    v_deviceIdCh3 NUMBER;
    v_t3Ch3       NUMBER;
    v_t1Ch3       NUMBER;
    v_t2Ch3       NUMBER;
    v_t4Ch3       NUMBER;
    v_t5Ch3       NUMBER;
    v_t6Ch3       NUMBER;
    v_t7Ch3       NUMBER;
    v_t8Ch3       NUMBER;

    v_channel4    elmos_opt.json;
    v_deviceIdCh4 NUMBER;
    v_t3Ch4       NUMBER;
    v_t1Ch4       NUMBER;
    v_t2Ch4       NUMBER;
    v_t4Ch4       NUMBER;
    v_t5Ch4       NUMBER;
    v_t6Ch4       NUMBER;
    v_t7Ch4       NUMBER;
    v_t8Ch4       NUMBER;

    v_deviceIdHost   NUMBER;
    v_deviceIdEqp    NUMBER;
    v_deviceIdEqpBis NUMBER;
BEGIN
v_json      := elmos_opt.json(in_json);
v_json_keys := v_json.get_keys();

FOR i IN 1 .. v_json_keys.count LOOP
  v_elseNr := v_json_keys.get(i).get_string;
  v_json_else_obj := elmos_opt.json(v_json.get(v_elseNr));
  v_pce           := v_json_else_obj.get('PCE').get_string;

  v_channel1    := elmos_opt.json(v_json_else_obj.get('CHANNEL1'));
  v_protocolCh1 := v_channel1.get('PROTOCOL').get_string;
  v_portCh1 := v_channel1.get('PORT').get_number;
  v_deviceIdCh1 := v_channel1.get('DEVICE_ID').get_number;
  v_t3Ch1 := v_channel1.get('T3_TIMEOUT').get_number;
  v_t1Ch1 := v_channel1.get('T1_TIMEOUT').get_number;
  v_t2Ch1 := v_channel1.get('T2_TIMEOUT').get_number;
  v_t4Ch1 := v_channel1.get('T4_TIMEOUT').get_number;
  v_t5Ch1 := v_channel1.get('T5_TIMEOUT').get_number;
  v_t6Ch1 := v_channel1.get('T6_TIMEOUT').get_number;
  v_t7Ch1 := v_channel1.get('T7_TIMEOUT').get_number;
  v_t8Ch1 := v_channel1.get('T8_TIMEOUT').get_number;

  v_channel2      := elmos_opt.json(v_json_else_obj.get('CHANNEL2'));
  v_remoteHostCh2 := v_channel2.get('REMOTE_HOST').get_string;
  v_protocolCh2 := v_channel2.get('PROTOCOL').get_string;
  v_portCh2 := v_channel2.get('PORT').get_number;
  v_deviceIdCh2 := v_channel2.get('DEVICE_ID').get_number;
  v_t3Ch2 := v_channel2.get('T3_TIMEOUT').get_number;
  v_t1Ch2 := v_channel2.get('T1_TIMEOUT').get_number;
  v_t2Ch2 := v_channel2.get('T2_TIMEOUT').get_number;
  v_t4Ch2 := v_channel2.get('T4_TIMEOUT').get_number;
  v_t5Ch2 := v_channel2.get('T5_TIMEOUT').get_number;
  v_t6Ch2 := v_channel2.get('T6_TIMEOUT').get_number;
  v_t7Ch2 := v_channel2.get('T7_TIMEOUT').get_number;
  v_t8Ch2 := v_channel2.get('T8_TIMEOUT').get_number;

  v_channel3    := elmos_opt.json(v_json_else_obj.get('CHANNEL3'));
  v_deviceIdCh3 := v_channel3.get('DEVICE_ID').get_number;
  v_t3Ch3 := v_channel3.get('T3_TIMEOUT').get_number;
  v_t1Ch3 := v_channel3.get('T1_TIMEOUT').get_number;
  v_t2Ch3 := v_channel3.get('T2_TIMEOUT').get_number;
  v_t4Ch3 := v_channel3.get('T4_TIMEOUT').get_number;
  v_t5Ch3 := v_channel3.get('T5_TIMEOUT').get_number;
  v_t6Ch3 := v_channel3.get('T6_TIMEOUT').get_number;
  v_t7Ch3 := v_channel3.get('T7_TIMEOUT').get_number;
  v_t8Ch3 := v_channel3.get('T8_TIMEOUT').get_number;

  v_channel4    := elmos_opt.json(v_json_else_obj.get('CHANNEL4'));
  v_deviceIdCh4 := v_channel4.get('DEVICE_ID').get_number;
  v_t3Ch4 := v_channel4.get('T3_TIMEOUT').get_number;
  v_t1Ch4 := v_channel4.get('T1_TIMEOUT').get_number;
  v_t2Ch4 := v_channel4.get('T2_TIMEOUT').get_number;
  v_t4Ch4 := v_channel4.get('T4_TIMEOUT').get_number;
  v_t5Ch4 := v_channel4.get('T5_TIMEOUT').get_number;
  v_t6Ch4 := v_channel4.get('T6_TIMEOUT').get_number;
  v_t7Ch4 := v_channel4.get('T7_TIMEOUT').get_number;
  v_t8Ch4 := v_channel4.get('T8_TIMEOUT').get_number;

  v_deviceIdHost := v_json_else_obj.get('DEVICE_ID_HOST').get_number;
  v_deviceIdEqp := v_json_else_obj.get('DEVICE_ID_EQP').get_number;

  IF v_json_else_obj.exist('DEVICE_ID_EQP_BIS') THEN
    v_deviceIdEqpBis := v_json_else_obj.get('DEVICE_ID_EQP_BIS').get_number;
  END IF;
END LOOP;
END setFDC_DATA;

[有篇文章建议将Clob分成几块,但是如果Clob是输入参数,我该如何在过程中使用它呢?

我得到的错误是:

PLS-00172: string literal too long

运行我的测试脚本以测试我的过程后,抛出此错误:

declare 
in_json clob;
begin
   -- Call the procedure
   in_json := 'very long json String';
   EA_JAMIE.set_FDC_Data(in_json => in_json);
end;

如何将输入的json分成几块?我从未使用过Clobs,也许我针对此错误找到的答案也适用于我的情况,但我不知道如何解决。对我来说,PL / SQL也是一个相当新的事物。

json plsql clob
1个回答
0
投票

您得到的错误是您的literal太长。文字只能包含4000个字符。这里的文字表示在调用过程之前将in_json设置为的值。您不能拥有此:

in_json := 'some text that is longer than 4000 characters';

请参见有关文字here的Oracle文档。

您可以通过将文字的一小部分一起添加到CLOB中,然后将其传递到过程中来作弊。这是一个愚蠢的例子。您可以将49k字符的JSON切成4k字符的块,可以使用NP ++或某些文本编辑器在每4000个字符中插入一个换行符,然后对每个块进行一个变量,然后将它们附加在一起。您甚至可以抛弃变量并将文字直接放入to_clob()中,但这会使此破解更加糟糕。

DECLARE
  v_s1   VARCHAR2(4000) := lpad('x',
                                4000,
                                'x');
  v_s2   VARCHAR2(4000) := lpad('x',
                                4000,
                                'x');
  v_s3   VARCHAR2(4000) := lpad('x',
                                4000,
                                'x');
  v_clob CLOB;
BEGIN
  dbms_lob.createtemporary(lob_loc => v_clob,
                           cache   => FALSE);
  dbms_lob.append(dest_lob => v_clob,
                  src_lob  => to_clob(v_s1));
  dbms_lob.append(dest_lob => v_clob,
                  src_lob  => to_clob(v_s2));
  dbms_lob.append(dest_lob => v_clob,
                  src_lob  => to_clob(v_s3));

  dbms_output.put_line(dbms_lob.getlength(lob_loc => v_clob));
END;
/

我假设您正在作为单元测试来执行此操作,并且in_json最终将来自其他地方。

© www.soinside.com 2019 - 2024. All rights reserved.