PlSql翻译函数问题
我创建了一个光标来选择实际数据,并循环遍历它,输出原始值和转换为数字后的值。应用程序偶尔会抛出无效数字错误。下面是我的测试(不包括 select 语句)代码和输出。
LOOP
FETCH myCursor into v_answer;
EXIT WHEN myCursor%notfound;
DBMS_OUTPUT.PUT_LINE('Raw answer: ' || v_answer );
v_instr := INSTR(v_answer, '.',1 , 2) ;
v_number := TO_NUMBER(REPLACE(TRANSLATE (CASE v_instr
WHEN 0 THEN UPPER(v_answer)
ELSE 0
END,'ABCDEFGHIJKLMNOPQURSTWVXYZ+<>:',' '), ' ',''));
DBMS_output.put_line('As number: ' || v_number);
这是输出:
Raw answer: 4
As number: 4
Raw answer: 3
As number: 3
Raw answer: 1.00
As number: 1
Raw answer: <3
我收到:
PL/SQL:数字或值错误:字符到数字转换错误
...当原始答案为“<3”时。
请注意,应用程序使用的实际代码如下所示:
AND TO_NUMBER(REPLACE(TRANSLATE ( decode( INSTR(hra_ans.answer_text, '.',1 , 2), 0 , UPPER(hra_ans.answer_text) , 0),'ABCDEFGHIJKLMNOPQURSTWVXYZ+<>:',' '), ' ',''))
并且是动态 sql 字符串中的 where 子句的一部分。我已将解码语句替换为 case 语句,因为我收到一个函数或伪列“DECODE”可能仅在 SQL 语句中使用的错误。
最后,我的问题是:
- 为什么翻译函数不替换小于号以及
- ORA-1722 和 ORA-06502 错误之间的区别(通俗地说)是什么?
编辑:我注意到,当我将 case 语句更改为: 时
CASE v_instr
WHEN 0 THEN UPPER(v_answer)
ELSE '0'
,
我不再收到 06502 错误。通过查看我发布的原始代码行,是否有关于可能导致无效数字错误的任何建议(假设不考虑要翻译的字符串中不存在字符)?或者,是否有更好的方法来完成原始开发人员试图做的事情?
以下是变量声明:
v_answer varchar2(2000);
v_number number;
v_instr number;
I've created a cursor to select the actual data, and loop through it outputting the raw value and the value after it was converted to a number. The application occasionally throws invalid number errors. Below is my test (not including the select statement) code and the output.
LOOP
FETCH myCursor into v_answer;
EXIT WHEN myCursor%notfound;
DBMS_OUTPUT.PUT_LINE('Raw answer: ' || v_answer );
v_instr := INSTR(v_answer, '.',1 , 2) ;
v_number := TO_NUMBER(REPLACE(TRANSLATE (CASE v_instr
WHEN 0 THEN UPPER(v_answer)
ELSE 0
END,'ABCDEFGHIJKLMNOPQURSTWVXYZ+<>:',' '), ' ',''));
DBMS_output.put_line('As number: ' || v_number);
Here is the output:
Raw answer: 4
As number: 4
Raw answer: 3
As number: 3
Raw answer: 1.00
As number: 1
Raw answer: <3
I receive:
PL/SQL: numeric or value error: character to number conversion error
...when the Raw answer is '<3'.
Please note that the actual code used by the application looks like so:
AND TO_NUMBER(REPLACE(TRANSLATE ( decode( INSTR(hra_ans.answer_text, '.',1 , 2), 0 , UPPER(hra_ans.answer_text) , 0),'ABCDEFGHIJKLMNOPQURSTWVXYZ+<>:',' '), ' ',''))
and is part of the where clause in a dynamic sql string. I've replaced the decode statement with the case statement because I was getting an function or pseudo-column 'DECODE' may be used inside a SQL statement only error.
Finally, my questions are these:
- Why isn't the translate function replacing the less than sign and
- What is the difference (in layman's terms) between the ORA-1722 and ORA-06502 errors?
EDIT: I've noticed that when I change the case statement to:
CASE v_instr
WHEN 0 THEN UPPER(v_answer)
ELSE '0'
,
I no longer receive the 06502 error. From looking at the original code line I posted, are there any suggestions as to what may be causing the invalid number error (assuming that no characters exist in the string to be translated are not accounted for)? Or, is there a better way to accomplish what the original developer was attempting to do?
Here are the variable declarations:
v_answer varchar2(2000);
v_number number;
v_instr number;
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
首先, TRANSLATE 并没有取代 '<'符号,因为它没有机会。 CASE 语句在一个条件下计算为数字,在另一个条件下计算为字符。如果您的 CASE 的输出是一致的,我相信您的错误就会消失:
来自 asktom.com 上的此帖子:
编辑:
您对 regexp_replace 的使用看起来不错,但如果我对此进行编码,我会使用 CASE 而不是 DECODE 只是因为我认为它更容易阅读:
First, the TRANSLATE isn't replacing the '<' symbol because it's not getting the chance. The CASE statement is evaluating to a number in one condition and a char in the other. If the output of your CASE is consistent, I believe your errors go away:
From this post on asktom.com:
EDIT:
Your use of regexp_replace looks good, but if I were coding this I'd use CASE instead of DECODE just because I think it's easier to read: