如何在pl/sql中将49.000个字符长的json字符串处理为clob
我有一个超过49k个字符的很长的json字符串,所以它不适合clob。 我有一个将json字符串作为clob输入的过程。在那里,我想读出所有值并将它们插入我的表中。如果我将json字符串变小以进行测试,那么一切都可以正常工作。但正如我所说,json字符串的长度超过49k个字符 我的程序的头部如下所示:如何在pl/sql中将49.000个字符长的json字符串处理为clob,json,plsql,clob,Json,Plsql,Clob,我有一个超过49k个字符的很长的json字符串,所以它不适合clob。 我有一个将json字符串作为clob输入的过程。在那里,我想读出所有值并将它们插入我的表中。如果我将json字符串变小以进行测试,那么一切都可以正常工作。但正如我所说,json字符串的长度超过49k个字符 我的程序的头部如下所示: PROCEDURE set_FDC_Data(in_json IN CLOB) IS v_json elmos_opt.json; v_json_keys
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分块?我从未使用过CLOB,也许我找到的关于这个错误的答案也适用于我的案例,但我不知道如何解决。PL/SQL对我来说也是一个相当新的东西。您得到的错误是您的文本太长。一个文本只能包含4000个字符。这里的Literal是指在调用过程之前在_json中设置的值。您不能拥有以下内容:
in_json := 'some text that is longer than 4000 characters';
有关文字(和其他字段)的最大长度,请参阅Oracle文档
可以通过将文本的小块附加到CLOB中,然后将其传递到过程中来作弊。这里有一个愚蠢的例子。您可以将49k个字符的JSON切割成4k个字符的块,可以使用NP++或某些文本编辑器每4000个字符插入一行新行,然后为每个块创建一个变量,然后将它们附加在一起。您甚至可以舍弃变量,将文本直接放入to_clob()中,但这将使这种攻击更加糟糕(请看)
我假设(希望)您将此作为一个单元测试来进行,而in_json最终将来自其他地方
编辑:您可能还希望将CLOB作为输入输出而不是仅仅输入。这将导致(希望如此)PL/SQL通过引用传递值,而不是通过值复制数据,从而在程序中节省内存和开销。您可以在Oracle文档中阅读有关NOCOPY的详细信息,因为存在可以忽略的例外情况
PROCEDURE set_FDC_Data(in_json IN OUT NOCOPY CLOB) IS
49k个字符将适合clob。我认为clob的上限约为2gb。您可能在某处隐式地将字符串转换为varchar2。@KirillLeontev我认为CLOB接近4GB。即使是2GB,也足以容纳49k个字符。我同意另一部分。如果您提供完整的过程会更好,这样会更容易调试。我添加了过程,谢谢大家的帮助!elmos_opt是您创建的任何类型吗?谢谢,它工作得非常好:)是的,它只是用于测试。实际的JSON字符串来自java应用程序。我是否也必须将CLOB分割成小块,还是在测试脚本中设置in_json时才发生此错误?无需分割CLOB。您只是为了绕过字符串文字限制而进行拆分。CLOB可能非常大。我在我的回答中加入了另一个关于NOCOPY的想法。
PROCEDURE set_FDC_Data(in_json IN OUT NOCOPY CLOB) IS