create or replace function trans_amount1(ip_number number) return VARCHAR2 is
  NEG VARCHAR2(100);
  Z   Varchar2(2);
  L_IP Number;
  L_ZeroFlag Integer:=1;
BEGIN
NEG:=Case When  Ip_Number<=0 Then '负'  When IP_Number=0 Then '零' End ;
L_IP:=ABS(IP_Number);
If NEG Is Null Then
For i in 1..Length(L_IP)
Loop
Z:=SubStr(L_IP,i,1);
If Z='0' then 
NEG:=NEG||'零';
ElsIf Z='.' then
If i=1 Then 
NEG:='零';
End If;
NEG:=NEG||'点';
L_ZeroFlag:=0;
Else
NEG:=NEG||SUBSTR('壹贰叁肆伍陆柒捌玖',To_Number(Z), 1);
If L_ZeroFlag=1 Then
If Instr(L_IP,'.')-i-1<>0 Then
NEG:=NEG||SUBSTR('拾佰仟万亿拾佰仟万', Instr(L_IP,'.')-i-1, 1);
End if;
End If;
End If;
End Loop;
End if;
Return NEG||' 吨';
END trans_amount1;我现在有个数字转变大写的函数出现了点问题,我解决不了了!
现在的问题是 整数和小数点前一位是零的有问题,例如:1. 11吨翻译 后为壹仟壹佰 吨
2. 10.289吨翻译 后为壹拾零点贰捌玖 吨

解决方案 »

  1.   

    整数问题:
    If Instr(L_IP,'.')-i-1 <>0 Then 
    NEG:=NEG ¦ ¦SUBSTR('拾佰仟万亿拾佰仟万', Instr(L_IP,'.')-i-1, 1); 
    End if; 这里,整数是没有'.'的,所以,Instr(L_IP,'.')-i-1
    算出来是负数,因此substr时负数表示从末尾开始数,然后
    截取
      

  2.   

    记得看书的时候看到过oracle提供了一个语音比较函数(看两句话的发音的相似程度),不知道可不可用在你这里,有兴趣的话可以自己搜搜看
      

  3.   

    create or replace function NUM_UPPER(ip_number number) return VARCHAR2 is
      NEG VARCHAR2(100);
      Z   VARCHAR2(100);
      L_IP Number;
      INSTR_LENGTH NUMBER ;
      AD VARCHAR2(100);--小數點后
      BC NUMBER;--小數點前
    BEGIN
    L_IP:=ABS(IP_Number);
    INSTR_LENGTH := INSTR(L_IP,'.');--只有小數時
    IF INSTR_LENGTH = 1 THEN
      NEG := '零点';
      For i in 2..Length(L_IP) Loop
        Z:=SUBSTR(L_IP,I,1);
        IF Z = '0' THEN
          NEG := NEG||'零';
        ELSE
          NEG := NEG||SUBSTR('一二三四五六七八九',TO_NUMBER(Z),1);
        END IF;
      END LOOP;
    --整數時
    ELSIF INSTR_LENGTH = 0 THEN
      For i in 1..Length(L_IP) Loop
        Z:=SUBSTR(L_IP,I,1);
        IF Z <> '0' THEN
          NEG := NEG || SUBSTR('一二三四五六七八九',TO_NUMBER(Z),1)||SUBSTR('$十百千万十百千意十百千',Length(L_IP)-I+1,1);
        ELSE
          IF I <> Length(L_IP) THEN
            NEG := NEG || '零';
          END IF;
        END IF;
      END LOOP;
    ELSE
      BC := TO_NUMBER(SUBSTR(L_IP,1,INSTR_LENGTH-1));
      AD := (SUBSTR(TO_CHAR(L_IP),INSTR_LENGTH+1,Length(L_IP)-INSTR_LENGTH));
        For i in 1..Length(BC) Loop
          Z:=SUBSTR(BC,I,1);
          IF Z <> '0' THEN
            NEG := NEG || SUBSTR('一二三四五六七八九',TO_NUMBER(Z),1)||SUBSTR('$十百千万十百千意十百千',Length(BC)-I+1,1);
          ELSE
            IF I <> Length(BC) THEN
              NEG := NEG || '零';
            END IF;
          END IF;
        END LOOP;
        NEG := NEG || '点';
        For i in 1..Length(AD) Loop
          Z:=SUBSTR(AD,I,1);
          IF Z = '0' THEN
            NEG := NEG||'零';
          ELSE
            NEG := NEG||SUBSTR('一二三四五六七八九',TO_NUMBER(Z),1);
          END IF;
        END LOOP;
    END IF;
    NEG := REPLACE(REPLACE(SUBSTR(NEG,1,INSTR(NEG,'点')),'零零','零'),'$','') 
    ||SUBSTR(NEG,INSTR(NEG,'点')+1,LENGTH(NEG)-INSTR(NEG,'点'))||' TON';
    IF SUBSTR(NEG,2,1) = '十' AND SUBSTR(NEG,1,1) = '一' THEN
      NEG := SUBSTR(NEG,2,LENGTH(NEG));
    END IF;
    IF SUBSTR(NEG,INSTR(NEG,'点')-1,1)='零' THEN
      NEG := SUBSTR(NEG,1,INSTR(NEG,'点')-2)||SUBSTR(NEG,INSTR(NEG,'点'),LENGTH(NEG)-INSTR(NEG,'点')+1);
    END IF;
    RETURN (NEG);
    END NUM_UPPER;SQL> set serveroutput on
    SQL> declare
      2  a varchar2(100);
      3  begin
      4  a := NUM_UPPER(999912345600.01230456);
      5  dbms_output.put_line(a);
      6  end;
      7  /
    九千九百九十九意一千二百三十四万五千六百点零一二三零四五六 TON