public class TestForBuss {
HashMap paramMap = new HashMap();
public static void main(String[] args) {
}
public TestForBuss(){
paramMap.put("i", 5);
paramMap.put("j", 6);
paramMap.put("x", 66);
}
// 这个方法是递归的方法. 外部调用的时候判断最外层调用的地方得到的返回值,
// 是Error开头的,就抛出异常,异常的提示是Error开头的字符串. 否则string 转 double,作为最终结果.
public String test1(String formula_id){
System.out.println("-------");
// String formula_id = "A";
//获取公式body
ExeSQL tExeSQL = new ExeSQL();
String tSql = "select f_body from formula_body where f_id = '"+formula_id+"'";
SSRS tSSRSStr = tExeSQL.execSQL(tSql);
if (tSSRSStr.MaxRow == 0){
return "Error: 公式id不存在 :"+formula_id;
}
String fBody = "";
for (int n = 1; n <= tSSRSStr.MaxRow; n++) {
fBody = tSSRSStr.GetText(n,1);
}
System.out.println("公式"+formula_id+"的body:"+fBody);
//获取该公式的参数列表
String tSql2 = "select f_param,f_defaultvalue from formula_param "
+ "where f_id = '"+formula_id+"'";
SSRS tSSRSStr2 = tExeSQL.execSQL(tSql2);
String fBody2 = "";
//TODO check 不允许调用自己
for (int n = 1; n <= tSSRSStr2.MaxRow; n++) {
String param = tSSRSStr2.GetText(n,1);
String paramDefaultValue = tSSRSStr2.GetText(n,2);
//
// (设定一个规则. 简单参数用小写开头, 公式用大写开头)
// 在这个地方判断参数是简单的参数还是另一个公式.如果是公式不从map里取值,递归的调用本方法.
// retrun 的string如果是Error开头的, 直接return
//是否是简单的参数(而不是公式)
boolean isSampleParam = param.substring(0, 1).equals(param.substring(0, 1).toLowerCase());
if(isSampleParam){
//如果传入的map里没这个参数
if (paramMap.get(param) == null){
//就用默认值填充公式body
fBody = fBody.replaceAll(":"+param, paramDefaultValue);
}else{
//否则用map里的参数
fBody = fBody.replaceAll(":"+param, paramMap.get(param).toString());
}
}else{
String returnValue = test1(param);
//如果调用嵌套的公式时发生错误.
if(returnValue.startsWith("Error")){
return returnValue;
}else{
fBody = fBody.replaceAll(":"+param, returnValue);
}
}
}
//check 如果全部替换后还有参数,而不是全都是数字.
if(fBody.indexOf(":")>=0){
return "Error: 公式"+formula_id +"中参数没有全部都配置在 formula_param 里";
}
//计算结果
String tSql3 = "select "+fBody+" from dual";
System.out.println("计算公式"+formula_id+"调用sql:"+tSql3);
SSRS tSSRSStr3 = tExeSQL.execSQL(tSql3);
String result = "";
for (int n = 1; n <= tSSRSStr3.MaxRow; n++) {
result = tSSRSStr3.GetText(n, 1);
}
System.out.println("公式"+formula_id+"的result:"+result);
return result;
}
}
外面套个异常处理就完了,简单的一批
运行公式B的日志:
-------
公式B的body::j +:x + :A
-------
公式A的body::i + :j
计算公式A调用sql:select 5 + 6 from dual
公式A的result:11
计算公式B调用sql:select 6 +66 + 11 from dual
公式B的result:83