上面一篇已经介绍了如何实现整数的字符串相减,有了这个作为基础,只需要分别对整数和小数部分分别处理,并将结果规整返回即可:
SQL> create OR REPLACE FUNCTION F_STR_SUB(P_STR1 IN VARchar2, P_STR2 IN VARchar2) RETURN VARchar2 AS 2 3 V_INTEGER_STR1 VARchar2(32767) := NVL( 4 SUBSTR(P_STR1, 1, 5 CASE INSTR(P_STR1, ’.’) WHEN 0 THEN LENGTH(P_STR1) ELSE INSTR(P_STR1, ’.’) – 1 END 6 ), 0); 7 V_INTEGER_STR2 VARchar2(32767) := NVL( 8 SUBSTR(P_STR2, 1, 9 CASE INSTR(P_STR2, ’.’) WHEN 0 THEN LENGTH(P_STR2) ELSE INSTR(P_STR2, ’.’) – 1 END 10 ), 0); 11 V_OTHER_STR1 VARchar2(32767) := CASE INSTR(P_STR1, ’.’) 12 WHEN 0 THEN NULL ELSE SUBSTR(P_STR1, INSTR(P_STR1, ’.’) + 1) END; 13 V_OTHER_STR2 VARchar2(32767) := CASE INSTR(P_STR2, ’.’) 14 WHEN 0 THEN NULL ELSE SUBSTR(P_STR2, INSTR(P_STR2, ’.’) + 1) END; 15 V_LENGTH_OTHER_1 NUMBER := NVL(LENGTH(V_OTHER_STR1), 0); 16 V_LENGTH_OTHER_2 NUMBER := NVL(LENGTH(V_OTHER_STR2), 0); 17 V_RESULT1 VARchar2(32767); 18 V_RESULT2 VARchar2(32767); 19 20 FUNCTION F_SUB_STR(P_SUB1 IN VARchar2, P_SUB2 IN VARchar2) RETURN VARchar2 AS 21 V_LENGTH1 NUMBER DEFAULT LENGTH(P_SUB1); 22 V_LENGTH2 NUMBER DEFAULT LENGTH(P_SUB2); 23 V_RES1 VARchar2(32767); 24 V_RES2 VARchar2(32767); 25 BEGIN 26 IF SUBSTR(P_SUB1, 1, 1) = ’-’ THEN 27 IF SUBSTR(P_SUB2, 1, 1) = ’-’ THEN 28 RETURN F_SUB_STR(SUBSTR(P_SUB2, 2), SUBSTR(P_SUB1, 2)); 29 ELSE 30 RETURN ’-’ || F_STR_ADD(SUBSTR(P_SUB1, 2), P_SUB2); 31 END IF; 32 ELSE 33 IF SUBSTR(P_SUB2, 1, 1) = ’-’ THEN 34 RETURN F_STR_ADD(SUBSTR(P_SUB1, 2), P_SUB2); 35 END IF; 36 END IF; 37 IF V_LENGTH1 > 37 AND V_LENGTH2 > 37 THEN 38 V_RES1 := F_SUB_STR(SUBSTR(P_SUB1, 1, V_LENGTH1 – 37), SUBSTR(P_SUB2, 1, V_LENGTH2 – 37)); 39 V_RES2 := F_SUB_STR(SUBSTR(P_SUB1, V_LENGTH1 – 36), SUBSTR(P_SUB2, V_LENGTH2 – 36)); 40 IF SUBSTR(V_RES1, 1, 1) = ’-’ THEN 41 IF SUBSTR(V_RES2, 1, 1) = ’-’ OR LTRIM(V_RES2, ’0’) IS NULL THEN 42 RETURN V_RES1 || SUBSTR(V_RES2, 2); 43 ELSE 44 RETURN ’-’ || F_SUB_STR(SUBSTR(V_RES1, 2), ’1’) 45 || F_STR_ADD(F_SUB_STR(LPAD(’9’, 37, ’9’), V_RES2), ’1’); 46 END IF; 47 ELSIF LTRIM(V_RES1, ’0’) IS NULL THEN 48 RETURN V_RES2; 49 ELSE 50 IF SUBSTR(V_RES2, 1, 1) = ’-’ THEN 51 RETURN F_SUB_STR(V_RES1, 1) 52 || F_STR_ADD(F_SUB_STR(LPAD(’9’, 37, ’9’), SUBSTR(V_RES2, 2)), ’1’); 53 ELSE 54 RETURN V_RES1 || V_RES2; 55 END IF; 56 END IF; 57 ELSIF V_LENGTH2 > 37 THEN 58 V_RES1 := F_SUB_STR(’0’, SUBSTR(P_SUB2, 1, V_LENGTH2 – 37)); 59 V_RES2 := F_SUB_STR(P_SUB1, SUBSTR(P_SUB2, V_LENGTH2 – 36)); 60 IF SUBSTR(V_RES1, 1, 1) = ’-’ THEN 61 IF SUBSTR(V_RES2, 1, 1) = ’-’ OR LTRIM(V_RES2, ’0’) IS NULL THEN 62 RETURN V_RES1 || SUBSTR(V_RES2, 2); 63 ELSE 64 RETURN ’-’ || F_SUB_STR(SUBSTR(V_RES1, 2), ’1’) 65 || F_STR_ADD(F_SUB_STR(LPAD(’9’, 37, ’9’), V_RES2), ’1’); 66 END IF; 67 ELSIF LTRIM(V_RES1, ’0’) IS NULL THEN 68 RETURN V_RES2; 69 ELSE 70 IF SUBSTR(V_RES2, 1, 1) = ’-’ THEN 71 RETURN F_SUB_STR(V_RES1, 1) 72 || F_STR_ADD(F_SUB_STR(LPAD(’9’, 37, ’9’), SUBSTR(V_RES2, 2)), ’1’); 73 ELSE 74 RETURN V_RES1 || V_RES2; 75 END IF; 76 END IF; 77 ELSIF V_LENGTH1 > 37 THEN 78 V_RES1 := SUBSTR(P_SUB1, 1, V_LENGTH1 – 37); 79 V_RES2 := F_SUB_STR(SUBSTR(P_SUB1, V_LENGTH1 – 36), P_SUB2); 80 IF SUBSTR(V_RES1, 1, 1) = ’-’ THEN 81 IF SUBSTR(V_RES2, 1, 1) = ’-’ OR LTRIM(V_RES2, ’0’) IS NULL THEN 82 RETURN V_RES1 || SUBSTR(V_RES2, 2); 83 ELSE 84 RETURN ’-’ || F_SUB_STR(SUBSTR(V_RES1, 2), ’1’) 85 || F_STR_ADD(F_SUB_STR(LPAD(’9’, 37, ’9’), V_RES2), ’1’); 86 END IF; 87 ELSIF LTRIM(V_RES1, ’0’) IS NULL THEN 88 RETURN V_RES2; 89 ELSE 90 IF SUBSTR(V_RES2, 1, 1) = ’-’ THEN 91 RETURN F_SUB_STR(V_RES1, 1) 92 || F_STR_ADD(F_SUB_STR(LPAD(’9’, 37, ’9’), SUBSTR(V_RES2, 2)), ’1’); 93 ELSE 94 RETURN V_RES1 || V_RES2; 95 END IF; 96 END IF; 97 ELSE 98 RETURN SUBSTR(SIGN(TO_NUMBER(P_SUB1) – TO_NUMBER(P_SUB2)), -2, 1) 99 || LPAD(ABS(TO_NUMBER(P_SUB1) – TO_NUMBER(P_SUB2)), GREATEST(V_LENGTH1, V_LENGTH2), ’0’); 100 END IF; 101 END; 102 103 BEGIN 104 V_RESULT1 := F_SUB_STR(V_INTEGER_STR1, V_INTEGER_STR2); 105 V_RESULT2 := F_SUB_STR(RPAD(V_OTHER_STR1, GREATEST(V_LENGTH_OTHER_1, V_LENGTH_OTHER_2), ’0’), 106 RPAD(V_OTHER_STR2, GREATEST(V_LENGTH_OTHER_1, V_LENGTH_OTHER_2), ’0’)); 107 108 IF SUBSTR(V_RESULT1, 1, 1) = ’-’ THEN 109 IF SUBSTR(V_RESULT2, 1, 1) = ’-’ OR LTRIM(V_RESULT2, ’0’) IS NULL THEN 110 RETURN ’-’ || NVL(LTRIM(RTRIM(RTRIM(SUBSTR(V_RESULT1, 2) || ’.’ || SUBSTR(V_RESULT2, 2), ’0’), ’.’), ’0’), ’0’); 111 ELSE 112 RETURN ’-’ || NVL(LTRIM(RTRIM(RTRIM(F_SUB_STR(SUBSTR(V_RESULT1, 2), ’1’) || ’.’ 113 || F_STR_ADD(F_SUB_STR(LPAD(’9’, LENGTH(V_RESULT2), ’9’), V_RESULT2), ’1’) 114 , ’0’), ’.’), ’0’), ’0’); 115 END IF; 116 ELSIF LTRIM(V_RESULT1, ’0’) IS NULL THEN 117 RETURN NVL(RTRIM(’.’ || RTRIM(V_RESULT2, ’0’), ’.’), 0); 118 ELSE 119 IF SUBSTR(V_RESULT2, 1, 1) = ’-’ THEN 120 RETURN NVL(LTRIM(RTRIM(RTRIM(F_SUB_STR(V_RESULT1, ’1’) || ’.’ 121 || F_STR_ADD(F_SUB_STR(LPAD(’9’, LENGTH(V_RESULT2), ’9’), SUBSTR(V_RESULT2, 2)), ’1’) 122 , ’0’), ’.’), ’0’), ’0’); 123 ELSE 124 RETURN NVL(LTRIM(RTRIM(RTRIM(V_RESULT1 || ’.’ || V_RESULT2, ’0’), ’.’), ’0’), ’0’); 125 END IF; 126 END IF; 127 END; 128 / 函数已创建。 |
通过几个简单的例子验证一下结果:
SQL> select F_STR_SUB(’123.1293482734982379482374’, 2 ’812384.123412834991238234823794822342’) FROM DUAL; F_STR_SUB(’123.1293482734982379482374’,’812384.123412834991238234823794822342’) ——————————————————————————– -812260.994064561493000286586394822342 SQL> select F_STR_SUB(’812384.123412834991238234823794822342’, 2 ’123.1293482734982379482374’) FROM DUAL; F_STR_SUB(’812384.123412834991238234823794822342’,’123.1293482734982379482374’) ——————————————————————————– 812260.9994064561493000286586394822342 SQL> select F_STR_SUB(’812384.1293482734982379482374’, 2 ’123.123412834991238234823794822342’) FROM DUAL; F_STR_SUB(’812384.1293482734982379482374’,’123.123412834991238234823794822342’) ——————————————————————————– 812261.005935438506999713413605177658 SQL> select F_STR_SUB(’123.123412834991238234823794822342’, 2 ’812384.1293482734982379482374’) FROM DUAL; F_STR_SUB(’123.123412834991238234823794822342’,’812384.1293482734982379482374’) ——————————————————————————– |
我们一直都在努力坚持原创.......请不要一声不吭,就悄悄拿走。
我原创,你原创,我们的内容世界才会更加精彩!
【所有原创内容版权均属TechTarget,欢迎大家转发分享。但未经授权,严禁任何媒体(平面媒体、网络媒体、自媒体等)以及微信公众号复制、转载、摘编或以其他方式进行使用。】
微信公众号

TechTarget
官方微博

TechTarget中国
作者
相关推荐
-
控制合约 不再畏惧Oracle
许多公司都与Oracle有无限制授权协议,他们害怕离开这个协议,所以就证明他们在使用Oracle的软件,即使因为需求单独购买部分授权许可也可能总体是省钱的。
-
如何应对Oracle EBS实施中的六个挑战?
在18个月的时间里,Vitamix启动运行了Oracle电子商务套件(E-Business Suite,EBS),而且Vitamix还对诸如Oracle ATG Web Commerce等所有页面属性进行了重新整理,并实现了全球数据中心。
-
DBA支招:如何实现Oracle EBS 12.2.5升级
那些对于是否要将EBS进行升级持观望态度的Oracle数据库管理员们可以从一家研究公司获得一些启示。
-
Oracle的云产品“砸了自己脚”?
Sparc和Solaris都是Oracle云计划的一部分,但是硬件和支持人员的减少意味着本地Solaris和Sparc将变得更加稀少。