Drools decision table create object - drools

I want to convert the below rule to decision table,
when
customer:Customer(purchase > 1000)
person:Person()
then
person.markValuableCustomer(customer.id);
end
I tried to convert this to decision table but I am not sure how to declare the person object. As you can see in the excel I created a new Condition for it.
I tried in a CONDITION column as person:Person but I get some error saying condition has to be entered.
So how to create a object in decision table which has to be used in Action column ?
Please find the excel data just in case if image uploaded is not opening.
RuleTable HelloWorld1
CONDITION CONDITION ACTION
customer:CustomerInfo
customer.purchase > "$param" && customer.valid person:Person(); person.markValuableCustomer(customer.id)
Purchase
1000

You can use this trick:
RuleTable HelloWorld1
CONDITION CONDITION ACTION
customer:CustomerInfo person:Person()
customer.purchase > "$param" /*$param*/ person.mark(customer.id)
Purchase
1000 x
You can join the cells of the condition column so that a single 'x' is sufficient.

Related

How to Select or Filter out values with endsWith() in Mapping data flow

I would like to filter out all values that does not end with ":Q_TT".
I have tried with the following activities
My bronze data has a column named "pnt_name". One of the rows in the table ends with ":Q_TT" so I would expect that the Exists activity would pass that row through.
Custom expression in Exists1
endsWith(':Q_TT', pnt_name)
In the future I would like the SourceData dataset to hold the filter values.
Thanks very much
You should be using filter activity instead of exists activity for your case.
The pipeline(where you can see the 2 test cases of A and B:Q_TT:
Here is the preview of the filter activity, you should use an expression of endsWith(pnt_name, ":Q_TT") too. You can see A is removed and B:Q_TT is kept.

Iteration over a column in decision table _ODM

I have a decision table which looks like :
and my input to the decision table looks like this :
A = 1, B = 1,4,5 and C =1 .
The requirement is that the decision table processing should halt when the first match is encountered with the decision table . In this case , row number 1 (B =1 ) , it should not check for B=4 and 5.
Please advise how to achieve this logic. I am using ODM 8.9
Thanks.
One way to execute just a single row of a decision table is to use specify the Exit Criteria in the properties of the rule task in which the decision table appears. If the Exit Criteria is set to Rule Instance, then only one rule will fire -- after the first rule fires, the rule task will end. If your decision table is the only thing in the rule task then this should give the desired behavior. It would also work if your decision table was the first thing in the rule task to be evaluated, in terms of order and priority.

How to assign csv field value to SQL query written inside table input step in Pentaho Spoon

I am pretty new to Pentaho so my query might sound very novice.
I have written a transformation in which am using CSV file input step and table input step.
Steps I followed:
Initially, I created a parameter in transformation properties. The
parameter birthdate doesn't have any default value set.
I have used this parameter in postgresql query in table input step
in the following manner:
select * from person where EXTRACT(YEAR FROM birthdate) > ${birthdate};
I am reading the CSV file using CSV file input step. How do I assign the birthdate value which is present in my CSV file to the parameter which I created in the transformation?
(OR)
Could you guide me the process of assigning the CSV field value directly to the SQL query used in the table input step without the use of a parameter?
TLDR;
I recommend using a "database join" step like in my third suggestion below.
See the last image for reference
First idea - Using Table Input as originally asked
Well, you don't need any parameter for that, unless you are going to provide the value for that parameter when asking the transformation to run. If you need to read data from a CSV you can do that with this approach.
First, read your CSV and make sure your rows are ok.
After that, use a select values to keep only the columns to be used as parameters.
In the table input, use a placeholder (?) to determine where to place the data and ask it to run for each row that it receives from the source step.
Just keep in ming that the order of columns received by the table input (the columns out of the select values) is the same order that it will be used for the placeholders (?). This should not be a problem with your question that uses only one placeholder, but keep that in mind as you ramp up using Pentaho.
Second idea, using a Database Lookup
This is another approach where you can't personalize the query made to the database and may experience a better performance because you can set a "Enable cache" flag and if you don't need to use a function on your where clause this is really recommended.
Third idea, using a Database Join
That is my recommended approach if you need a function on your where clause. It looks a lot like the Table Input approach but you can skip the select values step and select what columns to use, repeat the same column a bunch of times and enable a "outer join" flag that returns the rows without result from the query
ProTip: If you feel the transformation running too slow, try to use multiple copies from the step (documentation here) and obviously make sure the table have the appropriate indexes in place.
Yes there's a way of assigning directly without the use of parameter. Do as follows.
Use Block this step until steps finish to halt the table input step till csv input step completes.
Following is how you configure each step.
Note:
Postgres query should be select * from person where EXTRACT(YEAR
FROM birthdate) > ?::integer
Check Execute for each row and Replace variables in in Table input step.
Select only the birthday column in CSV input step.

Sql case stetement to check existing records and taking one

I have two parameters X and Y
Rules for these are only one of them can be null. They both can be existing, it's ok but they both can't be null.
I'm using this to check if they exist in database so I can assign one and rest of the SP can continue inserting.
SELECT #Id=id FROM Table WHERE (No = #x) OR (No = #y)
What I want to add is if they are both existing I want the Id to be the Id of #x.
I can't get the Case Statement right in my mind. Normally this is a no brainer but somehow I managed to get stuck.
ISNULL() will take the first non null value it finds.
SELECT #Id=id FROM Table WHERE No = ISNULL(#x, #y)

How to avoid Extra condition while Drools rule sheet is converted in rules?

In this Drools sheet I am comparing a class variable with a variable of another class variable but the rule converted are not as expected. Is there a way to do this...
One thing is creating a problem and it is when this excel sheet is converted into rules the condition where I check stdId in college class is equals to id of Student class i.e. third column, the rule is generated as follows-
$c2: College(stdId == $s.id == "x")
The =="x" part is undesirable and creating trouble while running the rules.
What should be done to remove the extra undesired part.
The third column can be written as
CONDITION
$c2: College(stdId==$s.id)/*$param*/
match student id
x
x
...
The x is required to trigger insertion of the conditional expression from row 2.