PL/SQL 实现基本的四则运算
2010-04-19 13:19
393 查看
CREATE OR REPLACE PACKAGE BODY PACK_RISK_FUNCTION AS
--- 1 将符号替换成#号 或许可以用正则表达式,但是嫌麻烦还是直接用替换
FUNCTION CHANGE_OPERATOR(FORMULA VARCHAR2)
RETURN VARCHAR2
AS
V_FORMULA VARCHAR2(100);
BEGIN
V_FORMULA := REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(FORMULA,'(',''),')',''),'+','#'),'-','#'),'*','#'),'/','#');
RETURN V_FORMULA;
END CHANGE_OPERATOR;
/**---- 2 将字符串按照 # 解析成不同字段**/
---- 创建一个TABLE变量 CREATE OR REPLACE TYPE STR_SPLIT IS TABLE OF VARCHAR2 (4000);
---- 调用函数语句 SELECT * FROM TABLE(SUB_FORMULA(FORMULA))
FUNCTION SUB_FORMULA(FORMULA VARCHAR2)
RETURN STR_SPLIT PIPELINED
AS
V_LENGTH NUMBER :=LENGTH(FORMULA);----字符串长度
V_INDEX NUMBER; ---- #的位置
V_START NUMBER:=1; ---开始位置
BEGIN
WHILE V_START <= V_LENGTH LOOP
V_INDEX:= INSTR(FORMULA,'#',V_START);
IF V_INDEX =0 THEN
PIPE ROW(SUBSTR(FORMULA,V_START));
V_START :=V_LENGTH + 1;
ELSE
PIPE ROW(SUBSTR(FORMULA,V_START,V_INDEX-V_START));
V_START := V_INDEX + 1;
END IF;
END LOOP;
RETURN;
EXCEPTION
WHEN OTHERS THEN
DBMS_OUTPUT.PUT_LINE(SQLCODE || ' ' || SQLERRM);
RETURN;
END SUB_FORMULA;
/**
---3 四则运算函数**/
FUNCTION OPERATION_GLOBAL (FORMULA IN RISKITEMINFO.RECKONNAME%TYPE)
RETURN VARCHAR2
IS
FORMULA_V RISKITEMINFO.RECKONNAME%TYPE :='('||FORMULA||')';
V_FORMULA VARCHAR2(500); ------储存转成#号后的公式
FIELD_NO VARCHAR2(100); ------字段编号
FIELD_VALUE VARCHAR2(100); --- 数据值
FIELD_TYPE NUMBER(2); ---- 数据类型
RESULT_V NUMBER;
/* V_COUNT NUMBER;*/
R_RESULT VARCHAR2(100);
BEGIN
------ 调用CHANGE_OPERATOR函数,将四则运算符号转换成#
V_FORMULA :=PACK_RISK_FUNCTION.CHANGE_OPERATOR(FORMULA);
-----创建游标C1_CURSOR 用于保存 公式分割后的字段名
DECLARE
CURSOR C1_CURSOR IS
SELECT * FROM TABLE(PACK_RISK_FUNCTION.SUB_FORMULA(V_FORMULA));
BEGIN
OPEN C1_CURSOR;
FETCH C1_CURSOR INTO FIELD_NO;
WHILE C1_CURSOR%FOUND LOOP
-----根据字段名查找最后日期的数据进行计算
SELECT A.FIELDTYPE,B.FIELDVALUE INTO FIELD_TYPE,FIELD_VALUE FROM RISKRAWDATAFIELD A,RISKRAWDATAVALUE B
WHERE B.RAWDATAFIELDID=A.ID AND A.FIELDNO = FIELD_NO AND DATADATE =(SELECT MAX(DATADATE) FROM RISKRAWDATAVALUE WHERE RAWDATAFIELDID= A.ID);
-----将公式中字段名与数据进行替换最终得到算式
FORMULA_V := REPLACE(FORMULA_V,FIELD_NO,FIELD_VALUE);
FETCH C1_CURSOR INTO FIELD_NO;
END LOOP;
CLOSE C1_CURSOR;
END;
------ 执行计算
EXECUTE IMMEDIATE 'SELECT'||FORMULA_V||' FROM DUAL' INTO RESULT_V;
---- 结果返回字符串,并四舍五入到小数点后4位
R_RESULT := TO_CHAR(ROUND(RESULT_V,4),'fm99999999990.9999');
RETURN R_RESULT;
EXCEPTION
WHEN OTHERS THEN
DBMS_OUTPUT.PUT_LINE(SQLCODE || ' ' || SQLERRM);
R_RESULT := 'X';
RETURN R_RESULT;
END;
-----判断公式中的字段是否被启用
-----创建游标C1_CURSOR 用于保存 公式分割后的字段名
DECLARE
CURSOR C1_CURSOR IS
SELECT * FROM TABLE(PACK_RISK_FUNCTION.SUB_FORMULA(V_FORMULA));
BEGIN
OPEN C1_CURSOR;
FETCH C1_CURSOR INTO FIELD_NO;
WHILE C1_CURSOR%FOUND LOOP
SELECT COUNT(*) INTO V_COUNT FROM RISKRAWDATAFIELD WHERE FIELDNO =FIELD_NO AND ISALIVE =1;
IF V_COUNT = 0 THEN
R_RESULT:= '公式中存在无效数据项';
RETURN R_RESULT;
END IF;
FETCH C1_CURSOR INTO FIELD_NO;
END LOOP;
CLOSE C1_CURSOR;
END;
RETURN R_RESULT;
EXCEPTION
WHEN OTHERS THEN
DBMS_OUTPUT.PUT_LINE(SQLCODE || ' ' || SQLERRM);
R_RESULT :='公式格式错误';
RETURN R_RESULT;
END;
END;
相关文章推荐
- Oracle_PL/SQL的基本写法_BEGIN_END块结构及简单的事务实现
- Oracle_PL/SQL的基本写法_BEGIN_END块结构及简单的事务实现
- PL/SQL的基本写法、BEGIN_END块结构及简单的事务实现
- Oracle_PL/SQL的基本写法_BEGIN_END块结构及简单的事务实现
- 实现自动生成30道四则运算题目(3)
- 实现自动生成30道四则运算题目(4)
- 使命栈(stack)实现一个简易的四则运算计算器
- PL/SQL 实现行列转换
- SQL Server中导入/导出 Excel (包括SQL实现和Net代码实现)的基本方法 .
- ASP实现SQL语句日期格式的加减运算
- 在pl/sql 里实现index 索引 效果
- C++实现对数学基本运算表达式的解析
- JS实现的简单四则运算计算器功能示例
- 3.结对编程成果报告(小学生四则运算的出题程序,Java实现)
- PL/SQL Cursor游标的基本使用
- oracle-PL/SQL基本语法
- 基于hibernate的基本dao接口与实现 及 sql模糊查询特殊字符处理 及 struts 特殊字符在界面正常回显
- PL/SQL通过修改配置文件的方式实现数据库的连接
- 利用ANTLR4实现一个简单的四则运算计算器
- 在pl/sql中使用exp/imp工具实现oracle数据导出/导入