sql - 如果超过 78 个字符,则使用 TIMESTAMP 的 TO_CHAR 会引发 ORA-01877

标签 sql oracle timestamp to-char

我遇到了一个奇怪的问题

我正在尝试将一些数字转换为“单词”,只需这样做:

TO_CHAR(TO_TIMESTAMP(LPAD( nvl(trunc(99999999),0) , 9, '0'), 'FF9'),'FFSP')      AS amt_in_words

效果很好,输出是 “九千九百九十九千九百九十九”

但是当我们尝试输入像 99999998 这样的数字时会发生什么?

TO_CHAR(TO_TIMESTAMP(LPAD( nvl(trunc(99999998),0) , 9, '0'), 'FF9'),'FFSP')      AS amt_in_words

它抛出错误“ORA-01877:字符串对于内部缓冲区来说太长”

嗯,这是一个较小的数字,它应该可以工作,但事实并非如此 我的理论是:它失败了,因为结果文本的长度是 79 个字符,并且由于某种原因失败了

suggestion 1:使用强制转换(EXPR as VARCHAR(100) ) 但它给出了同样的错误

有什么想法吗?

澄清: 不幸的是,我正在开发 Oracle Fusion BI buplisher,似乎我无法使用任何 Pl/sql 过程,只能使用普通的选择查询

最佳答案

PL/SQL 似乎不会遇到同样的问题,因此您可以编写自己的函数来进行转换:

create or replace function spell_number(p_number number) return varchar2 is
  l_str varchar2(200);
begin
  l_str := to_char(to_timestamp(lpad(nvl(trunc(p_number), 0) , 9, '0'), 'FF9'), 'FFSP');
  return l_str;
end;
/

那么更长的值也可以工作:

select spell_number(99999999) from dual;

AMT_IN_WORDS                                                                                       
----------------------------------------------------------------------------------------------------
NINETY-NINE MILLION NINE HUNDRED NINETY-NINE THOUSAND NINE HUNDRED NINETY-NINE                      


select spell_number(99999998) from dual;

AMT_IN_WORDS                                                                                       
----------------------------------------------------------------------------------------------------
NINETY-NINE MILLION NINE HUNDRED NINETY-NINE THOUSAND NINE HUNDRED NINETY-EIGHT                     

select spell_number(999999999) from dual;

AMT_IN_WORDS                                                                                       
----------------------------------------------------------------------------------------------------
NINE HUNDRED NINETY-NINE MILLION NINE HUNDRED NINETY-NINE THOUSAND NINE HUNDRED NINETY-NINE         

任何超过 9 位的数字都会忽略最低有效数字,但这似乎是 SP 格式的限制:

with t (num) as (
  select 99999998 from dual
  union all select 99999999 from dual
  union all select 999999999 from dual
  union all select 1000000000 from dual
  union all select 1000000001 from dual
  union all select 1000000010 from dual
  union all select 9999999999 from dual
  union all select 10000000000 from dual
  union all select 99999999999 from dual
  union all select 100000000000 from dual
)
select num, spell_number(num) as amt_in_words from t;

          NUM AMT_IN_WORDS                                                                                       
------------- ----------------------------------------------------------------------------------------------------
     99999998 NINETY-NINE MILLION NINE HUNDRED NINETY-NINE THOUSAND NINE HUNDRED NINETY-EIGHT                     
     99999999 NINETY-NINE MILLION NINE HUNDRED NINETY-NINE THOUSAND NINE HUNDRED NINETY-NINE                      
    999999999 NINE HUNDRED NINETY-NINE MILLION NINE HUNDRED NINETY-NINE THOUSAND NINE HUNDRED NINETY-NINE         
   1000000000 ONE HUNDRED  MILLION                                                                                
   1000000001 ONE HUNDRED  MILLION                                                                                
   1000000010 ONE HUNDRED  MILLION ONE                                                                            
   9999999999 NINE HUNDRED NINETY-NINE MILLION NINE HUNDRED NINETY-NINE THOUSAND NINE HUNDRED NINETY-NINE         
  10000000000 ONE HUNDRED  MILLION                                                                                
  99999999999 NINE HUNDRED NINETY-NINE MILLION NINE HUNDRED NINETY-NINE THOUSAND NINE HUNDRED NINETY-NINE         
 100000000000 ONE HUNDRED  MILLION                                                                                

关于sql - 如果超过 78 个字符,则使用 TIMESTAMP 的 TO_CHAR 会引发 ORA-01877,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36063137/

相关文章:

php - 合并多个SQL查询结果

mysql - 添加新表时 SQL 查询中断

sql - 如何从 Oracle SQL 的多个列中选择唯一值?

google-chrome - 如何在 Chrome 中使用 console.timeStamp?

python - pandas - 多索引切片未按预期调整索引值

sql - INSERT INTO 和 INSERT ALL INTO 之间的区别

sql - 将一列中的值解析为另一个表中的多列

Oracle SQL Developer 脚本输出不显示可读格式

java - java webapp和oracle中的日语字符

来自 postgresql 数据库的 Python 格式日期字符串