今天写了一段drools脚本,运行不报错,但是结果一直不正常,详细研究发现自定义方法函数调用是有坑的。
代码如下:
/*
抽取日期串中的月日,转成数字。输入串: 20220831,返回831.
*/
function int monthDay(String date) {
if (date == null){
return 0;
}
String md = date.substring(4);
return Integer.parseInt(md);
}
调用函数如下:
int monthDay = monthDay($a.data_date);
log.debug("monthDay = {}", monthDay);
if (monthDay <= 430) {
$a.corp_quar_date_2 = "0430";
} else if (monthDay <= 830) {
$a.corp_quar_date_2 = "0630";
} else if (monthDay <= 1031){
$a.corp_quar_date_2 = "0930";
} else {
$a.corp_quar_date_2 = "1231";
}
运行发现,无论$a.data_date是多少,结果一直是"1231"。
查看日志,发现log.debug调试输出是:
monthDay = org.mvel2.util.MethodStub@7d37f1c
估计是函数根本没执行,所以一直走到了else分支了。多次调试发现,改成如下写法就正确了:
//int monthDay = monthDay($a.data_date);
log.debug("monthDay = {}", monthDay($a.data_date));
if (monthDay($a.data_date) <= 430) {
$a.corp_quar_date_2 = "0430";
} else if (monthDay($a.data_date) <= 830) {
$a.corp_quar_date_2 = "0630";
} else if (monthDay($a.data_date) <= 1031){
$a.corp_quar_date_2 = "0930";
} else {
$a.corp_quar_date_2 = "1231";
}
然而,这样写法每次if比较都要调用一下函数,多浪费呀!我最后是把这个函数放java里了,不知大家由没有更好的办法。
最后的脚本如下:
int monthDay = DrlUtils.monthDay($a.data_date);
log.debug("monthDay = {}", monthDay);
if (monthDay <= 430) {
...
如下一段脚本,一直出很奇怪的错误。
log.trace("6) 公司投资级判定 -----");//消息里面的"()"也要配对!!!
if (($a.listed_company_flag == "T" || DrlUtils.in($a.exchange_cd, "1", "2", "3", "4"))
&& $a.debt_flag == "T"
&& $a.corp_fin_report_valid_flag_solo == "T"
&& $a.corp_fin_report_0_flag_solo_3years == "T"
&& $a.latest_quar_corp_fin_report_valid_flag_solo == "T"
&& $a.latest_quar_corp_fin_report_0_flag_solo == "T"){
...
}
看着不复杂,单规则编译老是出错:
[Error: [Error: was expecting type: java.lang.Boolean; but found type: <Unknown>]
[Near : {... ....}]
^
[Line: 1, Column: 0]]
[Near : {... ntl_overdue_flag == "F"; ....}]
多次实验,终于找到原因:日志里面有个不封闭的括号!!!
改成如下就好了:
log.trace("(6) 公司投资级判定 -----");//消息里面的"()"也要配对!!!
if (($a.listed_company_flag == "T" || DrlUtils.in($a.exchange_cd, "1", "2", "3", "4"))
&& $a.debt_flag == "T"
&& $a.corp_fin_report_valid_flag_solo == "T"
&& $a.corp_fin_report_0_flag_solo_3years == "T"
&& $a.latest_quar_corp_fin_report_valid_flag_solo == "T"
&& $a.latest_quar_corp_fin_report_0_flag_solo == "T"){
...
}
if else后面的花括号”{“不能放在新的一行,如下写法不行:
if (true)
{ //这里{不能换行
...
}
要写成如下:
if (true) {//这里的“{”不能换行
...
}
参见: https://blog.csdn.net/weixin_45357522/article/details/126538871
idea不支持直接对drl文件格式化,我们可以创建一个临时js,把then后面的语句复制到js文件里,对js文件格式化,再复制回去。