【问题标题】:ORA-06502: PL/SQL: numeric or value error: character to number conversion error using clob not workingORA-06502: PL/SQL: 数字或值错误: 使用 clob 的字符到数字转换错误不起作用
【发布时间】:2022-01-18 04:12:31
【问题描述】:

我想在 oracle 过程中为多个 JOBID's 选择数据,所以在这样做时我收到了错误

ORA-06502: PL/SQL: numeric or value error: character to number conversion error

出于这个原因,我将 JOBID 的数据类型更改为 CLOB,但仍然没有任何工作并出现相同的错误。

SELECT CAST( STR2TBL('7507, 22781, 24949, 187771, 189739, 185736, 185737, 187276, 187665, 186012, 185743,
187559, 195056, 185626, 186337, 186655, 187495, 185679, 186352, 187578, 189666, 186017, 186254, 190430, 
185176, 186243, 186389, 184861, 188567, 192888, 186283, 191680, 186355, 186775, 186776, 189203, 189910, 
184871, 184906, 186125, 186336, 186339, 186565, 190469, 192138, 187710, 190267, 189186, 191515, 187711, 
186442, 187866, 186351, 190211, 186159, 191145, 191377, 187859, 187952, 192877, 185906, 187533, 190735,
185907, 186248, 189255, 185625, 190941, 185449, 191380, 186106, 189510, 186360, 191302, 189611, 190617,
185792, 187083, 188226, 185288, 188150, 186903, 189377, 191694, 188053, 186112, 186683, 192014, 185416, 
191872, 185287, 185305, 190949, 186108, 186109, 189351, 186134, 188553, 188677, 189732, 187494, 188509,
192253, 189756, 191681, 186313, 189972, 191752, 185663, 186169, 188137, 188508, 185178, 192363, 185122,
190679, 187951, 190905, 194509, 194510, 203859, 194422, 195960, 199874, 202223, 204643, 204648, 204808, 
193250, 198709, 204132, 203977, 197526, 198293, 204636, 193779, 197365, 194224, 194842, 194657, 202435,
194597, 204664, 199924, 194526, 195664, 196277, 204668, 204671, 199873, 197154, 199879, 200267, 204798,
204806, 204028, 203714, 203858, 204650, 204658, 195039, 196382, 198780, 199991, 204942, 204947, 204955,
199989, 203400, 203409, 194846, 199896, 200558, 200726, 193576, 204633, 204667, 204674, 204675, 204911,
195745, 198303, 201390, 199988, 198405, 198826, 199871, 199926, 193249, 195256, 199877, 194266, 201870,
196115, 196186, 196949, 202114, 204338, 198203, 202113, 195171, 197902, 198215, 204566, 199990, 193851,
195746, 199872, 202511, 200136, 204600, 204634, 204635, 204646, 204651, 204653, 204654, 204665, 204670,
193058, 193260, 203220, 202043, 193061, 205345, 205192, 205033, 205267, 205400, 205249, 205324, 205351,
205117, 205141, 205142, 205289, 205285, 205016, 205151, 205395, 205220, 205100, 205113, 205140, 205105, 
10522, 3473, 676, 2626, 3474, 3116, 8246, 3478, 5136, 675, 6816, 2621, 2622, 2623, 2624, 3476, 3115, 526, 
2625, 2627, 4175, 674, 5873, 5874, 3475, 3114, 446, 8746, 12825, 16173, 12826, 20967, 25133, 32526, 30226' ) AS MYTABLETYPE ) FROM DUAL;

还有STR2TBL是我的内置函数

create or replace function         str2tbl( p_str in CLOB ) return myTableType
    as
        l_str   long default p_str || ',';
        l_n        number;
        l_data    myTableType := myTabletype();
    begin
        loop
            l_n := instr( l_str, ',' );
            exit when (nvl(l_n,0) = 0);
           l_data.extend;
           l_data( l_data.count ) := ltrim(rtrim(substr(l_str,1,l_n-1)));
           l_str := substr( l_str, l_n+1 );
       end loop;
       return l_data;
  END;

【问题讨论】:

  • 为什么l_str 被声明为long 而不是cloblong 已被弃用很长时间,很长很长,longlong。我相信超过2个十年。我不确定这是问题所在,但它不能帮助你。可能是当您传入的字符串超过 32k 时出现问题。
  • @JustinCave: 在传递clob 时,我在l_data( l_data.count ) := ltrim(rtrim(substr(l_str,1,l_n-1))); 行遇到expression is of wrong type 错误
  • 另外,如何限制传递的字符串..作为它的动态并且需要处理它

标签: oracle stored-procedures plsql


【解决方案1】:

您的过程效率低下,因为它不断用越来越小的子字符串覆盖CLOB

相反,您可以使用split_string function(将数据类型更改为CLOB)跟踪每个术语前后逗号的位置并从这些位置查找子字符串:

CREATE OR REPLACE TYPE stringlist AS TABLE OF VARCHAR2(20)
/

CREATE OR REPLACE FUNCTION split_String(
  i_str    IN  CLOB,
  i_delim  IN  VARCHAR2 DEFAULT ','
) RETURN stringlist DETERMINISTIC
AS
  p_result       stringlist := stringlist();
  p_start        NUMBER(5) := 1;
  p_end          NUMBER(5);
  c_len CONSTANT NUMBER(5) := LENGTH( i_str );
  c_ld  CONSTANT NUMBER(5) := LENGTH( i_delim );
BEGIN
  IF c_len > 0 THEN
    p_end := INSTR( i_str, i_delim, p_start );
    WHILE p_end > 0 LOOP
      p_result.EXTEND;
      p_result( p_result.COUNT ) := SUBSTR( i_str, p_start, p_end - p_start );
      p_start := p_end + c_ld;
      p_end := INSTR( i_str, i_delim, p_start );
    END LOOP;
    IF p_start <= c_len + 1 THEN
      p_result.EXTEND;
      p_result( p_result.COUNT ) := SUBSTR( i_str, p_start, c_len - p_start + 1 );
    END IF;
  END IF;
  RETURN p_result;
END;
/

那么你可以这样使用它:

SELECT column_value
FROM   TABLE(split_string(
         '7507, 22781, 24949, 187771, 189739, 185736, 185737, 187276, 187665, 186012, 185743, 187559, 195056, 185626, 186337, 186655, 187495, 185679, 186352, 187578, 189666, 186017, 186254, 190430, 185176, 186243, 186389, 184861, 188567, 192888, 186283, 191680, 186355, 186775, 186776, 189203, 189910, 184871, 184906, 186125, 186336, 186339, 186565, 190469, 192138, 187710, 190267, 189186, 191515, 187711, 186442, 187866, 186351, 190211, 186159, 191145, 191377, 187859, 187952, 192877, 185906, 187533, 190735, 185907, 186248, 189255, 185625, 190941, 185449, 191380, 186106, 189510, 186360, 191302, 189611, 190617, 185792, 187083, 188226, 185288, 188150, 186903, 189377, 191694, 188053, 186112, 186683, 192014, 185416, 191872, 185287, 185305, 190949, 186108, 186109, 189351, 186134, 188553, 188677, 189732, 187494, 188509, 192253, 189756, 191681, 186313, 189972, 191752, 185663, 186169, 188137, 188508, 185178, 192363, 185122, 190679, 187951, 190905, 194509, 194510, 203859, 194422, 195960, 199874, 202223, 204643, 204648, 204808, 193250, 198709, 204132, 203977, 197526, 198293, 204636, 193779, 197365, 194224, 194842, 194657, 202435, 194597, 204664, 199924, 194526, 195664, 196277, 204668, 204671, 199873, 197154, 199879, 200267, 204798, 204806, 204028, 203714, 203858, 204650, 204658, 195039, 196382, 198780, 199991, 204942, 204947, 204955, 199989, 203400, 203409, 194846, 199896, 200558, 200726, 193576, 204633, 204667, 204674, 204675, 204911, 195745, 198303, 201390, 199988, 198405, 198826, 199871, 199926, 193249, 195256, 199877, 194266, 201870, 196115, 196186, 196949, 202114, 204338, 198203, 202113, 195171, 197902, 198215, 204566, 199990, 193851, 195746, 199872, 202511, 200136, 204600, 204634, 204635, 204646, 204651, 204653, 204654, 204665, 204670, 193058, 193260, 203220, 202043, 193061, 205345, 205192, 205033, 205267, 205400, 205249, 205324, 205351, 205117, 205141, 205142, 205289, 205285, 205016, 205151, 205395, 205220, 205100, 205113, 205140, 205105, 10522, 3473, 676, 2626, 3474, 3116, 8246, 3478, 5136, 675, 6816, 2621, 2622, 2623, 2624, 3476, 3115, 526, 2625, 2627, 4175, 674, 5873, 5874, 3475, 3114, 446, 8746, 12825, 16173, 12826, 20967, 25133, 32526, 30226',
         ', '
       ));

db小提琴here

【讨论】:

  • 我现在在两个字符串之间获得空间,例如:'7507', ' 22781', ' 24949'
  • @hud 那是因为您的数据中有空格和换行符。如果您不想要它们,请从数据中删除它们(在输入时,就像我在答案中所做的那样,或者在拆分后修剪数据)。
  • 你能帮忙修剪一下这里的数据吗?以便我可以尝试检查
  • @hud 只需在 COLUMN_VALUE 输出上使用 TRIM (如果需要,使用它 3 次首先修剪空格,然后换行符 CHR(10) 第二次,然后再次空格第三次)。
  • 好的,但我想要的最终输出应该是这样的 '7507, 22781, 24949'.. 好的会尝试相应地更新你
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-03-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-04-25
相关资源
最近更新 更多