上面一篇已经介绍了如何实现整数的字符串相减,有了这个作为基础,只需要分别对整数和小数部分分别处理,并将结果规整返回即可:
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中国
作者
相关推荐
-
Collaborate 18大会:了解甲骨文云数据库和应用的进展
在Collaborate 18大会即将举行时,我们会发现,甲骨文用户社区的技术变化会略高于平常水平。 由独立甲 […]
-
甲骨文自治数据库亮相 带来云计算新希望
早前甲骨文还不在云计算公司之列,而现在该公司正在迅速弥补其失去的时间。甲骨文的云计算核心是甲骨文自治数据库(O […]
-
2017年12月数据库流行度排行榜 定格岁末排名瞬间
数据库知识网站DB-engines最近更新的2017年12月份数据库流行度排名情况是否能提供更多的看点呢?TechTarget数据库网站将与您分享12月份的榜单排名情况,让我们拭目以待。
-
2017年11月数据库流行度排行榜 半数以上数据库积分减少
数据库知识网站DB-engines更新了2016年11月份的数据库流行度排行榜。TechTarget数据库网站将与您一同关注11月份的榜单排名情况。