Oracle® Database Application Developer's Guide - Rules Manager and Expression Filter 10g Release 2 (10.2) Part Number B14288-01 |
|
|
View PDF |
A rule condition is expressed using the attributes defined in the event structure. For the travel services example, the rule condition is expressed using the attributes: Airline
, ToCity
, Return
, and Depart
, as follows:
Airline = 'Abcair' and ToCity = 'Orlando' and Return - Depart >=7
Because a rule condition for a primitive event structure can be represented as a standard SQL WHERE
clause conditional expression, the previous rule condition is shown without the XML markup. Were this rule condition to be represented with the XML markup, the expression would be as follows:
<condition> Airline = 'Abcair' and ToCity = 'Orlando' and Return - Depart >=7 </condition>
XML markup can be ignored in the case of rules defined for simple event structures because these cases usually involve simple usage. Because the rule condition specified for composite event structures involves complex constructs and must support incremental evaluation of rules, the condition expression is enhanced with some XML markup. This support is added as XML extensions to the conditional expressions that are typically in the SQL WHERE
clause. The XML tags provided identify different parts of a conditional expression and add special semantics to this expression.
To enable incremental evaluation of rules and support complex rule applications, the conditional expressions in the SQL WHERE
clause are extended with meaningful XML tags. The XML tags are provided to identify different parts of a conditional expression and add special semantics to these expressions.For example, the conditional expression (Flt.Airline = 'Abcair' and Flt.ToCity = 'Orlando' and Flt.CustId = Car.CustId and Car.CarType = 'Luxury'
) in the travel services rule has three parts, as follows:
Predicates defined on the primitive event AddFlight (Flt.Airline = 'Abcair' and Flt.ToCity = 'Orlando'
)
A predicate defined on the primitive event AddRentalCar (Car.CarType = 'Luxury'
)
A join predicate between the two primitive events (Flt.CustId = Car.CustId
)
Rules Manager provides XML tags to identify various parts of a complex conditional expression and support additional semantics. For example, the previous rule condition can be represented using XML tags as followsFoot 1 :
<condition> <and join="Flt.CustId = Car.CustId"> <object name="Flt"> Airline='Abcair' and ToCity='Orlando' </object> <object name="Car"> CarType = 'Luxury' </object> </and> </condition>
In this representation, the object elements capture the predicates specified for individual primitive events and one join attribute of the <and>
element captures the join predicate behavior between two primitive events. The rule condition in this format can be inserted into the rlm$rulecond
column of the corresponding rule class table. XML tags are provided to support more complex rule constructs. These tags are summarized in Figure 4-1 and Table 4-1 and are described in Chapter4 through Chapter4.
Figure 4-1 describes a hierarchical view of the supported XML tag elements and their attributes for the rule condition XML schema definition that is described in detail in Appendix F in the Rule Condition section. Table 4-1 shows a relational view of the same supported XML tag extensions showing the XPath and some notes about the elements and attributes.
Figure 4-1 Hierarchical View of the XML Tag Extensions
Table 4-1 Relational View of the XML Tag Extensions
XML Tag | Type | Parent | XPath | Number of Occurrences Allowed within Its Parent | Notes |
---|---|---|---|---|---|
condition |
Element |
None |
condition |
--- |
Denotes a conditional expression |
and |
Element |
condition |
condition/and |
One |
Combines predicates |
any |
Element |
condition |
condition/any |
One |
A substitute for "or"; true if any condition is met |
not |
Element |
and |
and/not |
One, as last child element |
Logical negation |
notany |
Element |
and |
and/notany |
One, as last child element |
Logical negation; detects non-occurrence |
object |
Element |
condition and any not notany |
condition/object and/object any/object not/object notany/object |
One Two or more objects Two or more objects One object Two or more objects |
Primitive event |
join |
Attribute |
and any not notany |
and/@join any/@join not/@join notany/@join |
One One One One |
Joins predicates |
sequence |
Attribute |
and any |
and/@sequence any/@sequence |
One One |
Specifies an ordered sequence Specifies any ordered sequence |
equal |
Attribute |
and any |
and/@equal any/@equal |
One One |
Joins predicates |
count |
Attribute |
any notany |
any/@count notany/@count |
One One |
Any n semantics Any n semantics |
by |
Attribute |
not notany |
not/@by notany/@by |
One One |
Deadline for non-occurrence Deadline for non-occurrence |
name |
Attribute |
object |
object/@name |
One |
Object name |
The rules defined for a composite event (consisting of two or more primitive events) may specify a condition on the order in which the primitive events should occur. This is called sequencing and it can be partial on a subset of primitive events, or it can be complete based on all the primitive events. Sequencing in rule applications is supported using the implicit timestamp attribute (rlm$crtTime
) that is included in each primitive event participating in a composite event.
The event creation times in the primitive events are used to enforce and detect sequencing in rule applications. For example, the rule considered in the travel services application can specify an additional predicate to offer the promotion only if the AddRentalCar
event is generated after the AddFlight
event. The rule condition can be extended to include this sequencing predicate, as follows:
<condition>
<and join="Flt.CustId = Car.CustId" sequence="yes">
<object name="Flt"> Airline='Abcair' and ToCity='Orlando' </object>
<object name="Car"> CarType = 'Luxury' </object>
</and>
</condition>
The sequence attribute in the preceding example ensures that the rule condition evaluates to true only if the matching primitive events occur in the order in which they are specified within the <and>
element. The sequence attribute can be replaced with a join predicate on the corresponding event creation times, shown as follows:
<condition>
<and join="Flt.CustId = Car.CustId and Car.rlm$CrtTime >= Flt.rlm$CrtTime">
<object name="Flt"> Airline='Abcair' and ToCity='Orlando' </object>
<object name="Car""> CarType = 'Luxury' </object>
</and>
</condition>
Sequencing can be used to detect partial ordering among primitive events (for example, using a join predicate on only two primitive events when there are three of them in the composite event). The rlm$CrtTime
attribute in the primitive event type can also be used to apply additional time constrains in the rule conditions. For example, the travel services rule may be valid only when the car reservations is made within 24 hours of making the flight reservation. This is indicated in the bolded text of the following example where the value 1 means one day. See Oracle Database Application Developer's Guide - Fundamentals for more information about performing date/timestamp arithmetic.
<condition>
<and join="Flt.CustId = Car.CustId and
Flt.rlm$CrtTime >= (Car.rlm$CrtTime - 1)"
sequence="Yes">
<object name="Flt"> Airline='Abcair' and ToCity='Orlando' </object>
<object name="Car"> CarType = 'Luxury' </object>
</and>
</condition>
Optionally, the call to the DBMS_RLMGR.PROCESS_RULES
procedure may pass an event with a specific event creation time. Within a primitive event, the rlm$CrtTime
attribute is treated as any other attribute in the event structure. However, when a value is not specified for this attribute, it is assigned a default value of SYSTIMESTAMP
(in the database). If an application is sensitive to the difference between the times at which the events are detected (in the application layer) and the times at which they are added to Rules Manager, it may choose to set the values for event creation times and add fully specified events to the rules class.
Rules with negation in their conditions are typically used to raise exceptions in business processes. For example, a rule using negation could be "If an order is placed by a Gold customer and the items are not shipped within 24 hours of the order placement, alert the representative". In this case, the rule is defined for a composite event consisting of two primitive events PlaceOrder
and ShipOrder
and the type created for the composite event structure is shown as follows:
CREATE or REPLACE TYPE OrderTrack AS OBJECT ( order PlaceOrder, -- primitive event type -- ship ShipOrder); -- primitive event type --
For a composite event, a rule defined with negation evaluates to true when one of the primitive events does not happen within a time delay of the other. So, negation always accompanies a time delay that is relative to the other primitive event or events in the composite event. For example, the rule condition for the order tracking rule can be captured as follows, where the bolded text in the following example, "sysdate +1", means by the end of the next day because the SQL datetime function SYSDATE
returns the current date and time of the operating system on which the database resides (taking into account the time zone of the database server's operating system that was in effect when the database was started).
<condition>
<and equal="order.orderId, ship.orderId">
<object name="order"> Type = 'Gold' </object>
<not by="sysdate+1">
<object name="ship"/> -- empty elem: no conditions on the primitive event --
</not>
</and>
</condition>
The <not>
XML element in the rule condition has the following semantics:
There can be only one <not>
element in a rule condition.
The <not>
element can only appear within an <and>
element (as a conjunction to other primitive events) and it should be the last element within the <and>
element.
The <not>
element is activated only when all the other primitive events in the composite events are detected.
The <not>
element can contain only one <object> element that represents a primitive event.The <notany>
element can be used in place of the <not>
element to support a notion of disjunction within the negation rule.
At the time of activation, the by
attribute of the <not>
element is executed to compute the deadline for the primitive events in the <not>
element. The value for the by
attribute can be expressed using the (database) SYSTIMESTAMP
(to be set to the time of activation) or any date attribute in the other primitive events (including the event creation time attributes discussed in Chapter4), or both. The SQL datetime function SYSTIMESTAMP
returns the system date including fractional seconds and time zone of the system on which the database resides. So, the rule condition in the preceding example can also be expressed as follows:
<condition>
<and equal="order.orderId, ship.orderId">
<object name="order"> Type = 'Gold' </object>
<not by="order.rlm$CrtTime+1">
<object name="ship"/>
</not>
</and>
</condition>
Another variant of the preceding rule is one that uses a user-supplied date in the deadline computation. For example, a ShipBy
attribute in the PlaceOrder
event can hold the time by which the shipment is expected and the deadline can be computed using this attribute, such as shown here:
<condition>
<and equal="order.orderId, ship.orderId">
<object name="order"> Type = 'Gold' </object>
<not by="order.ShipBy-1">
<object name="ship"/>
</not>
</and>
</condition>
Rules with negation involving a deadline other than SYSTIMESTAMP
are not allowed in a rule class with the AUTOCOMMIT
property turned off (see Chapter3). This also includes the rule classes configured for DMLEVENTS
(see Chapter3).
Rules involving negation constructs can be used to raise alerts (in corresponding rule actions) when a set of primitive events are generated out of order. In applications such as Workflow, rules are often used to enforce sequencing among various business events. The action of such rules is to raise an exception (alert an agent) when the events are detected out of order. A <not>
element without a hard deadline (no by
attribute) can be used to define such rules.
Consider a composite event with three primitive events: PlaceOrder
, PaymentReceived
, and ShipOrder
. A rule can be used to alert an agent (action) if the ShipOrder event is generated before the PaymentReceived
event is detected. (Note that there are alternate ways to model this application in a Workflow system, but this approach is used to explain the negation concept). For this example, the composite event structure and the rule condition are represented as follows:
CREATE or REPLACE TYPE OrderTrack AS OBJECT ( order PlaceOrder, -- primitive event type –- pay PaymentReceived, -- primitive event type -- ship ShipOrder); -- primitive event type -- <condition> <and equal="order.OrderId, pay.OrderId, ship.OrderId"> <object name="order"/> -- no conditions on the primitive events -- <object name="ship"/> <not> <object name="pay"/> </not> </and> </condition>
The previous example uses a <not>
element with no deadline specification (by
attribute) and thus this value defaults to SYSTIMESTAMP
(the time at which all other primitive events in the rule condition are detected). The sequence="yes" (Chapter4) property, such as shown in the following example, can be used to ensure ordering among the detected events.
<condition> <and equal="order.OrderId, pay.OrderId, ship.OrderId" sequence="yes"> <object name="order"/> -- no conditions on the primitive events -- <object name="ship"/> <not> <object name="pay"/> </not> </and> </condition>
In the previous rule condition, the deadline for the PaymentReceived
event is determined by the occurrence of the ShipOrder
event, which follows the corresponding PlaceOrder
event. In effect, the action associated with the preceding rule condition will be executed if the ShipOrder
event is detected before the PaymentReceived
event for a particular order.
The negation construct can often be used to detect the non-occurrence of two or more primitive events. For example, a rule such as "If an order is placed by a Gold customer and the items are not shipped within 24 hours of the order placement or if the order is not cancelled, alert the representative" uses negation on the two events, ShipOrder
and CancelOrder
. Such rule conditions can be expressed using a <notany>
element in the place of the <not>
element as shown in the following example:
<condition> <and equal="order.orderId, ship.orderId, cancel.orderId"> <object name="order"> Type = 'Gold' </object> <notany count=1 by="order.rlm$CrtTime+1"> <object name="ship"/> <object name="cancel"/> -- assuming a CancelOrder event -- </notany> </and> </condition>
The primitive events appearing within the <not>
or <notany>
element should not be referenced in the join
attribute specification of the <and>
element. However, they (primitive events) can be used within the EQUAL
property specifications. If there is a need to specify a join condition (other than those already captured by the EQUAL
property specifications), the join
attribute for the <not>
element can be used. The conditional expression specified for this join
attribute can reference all the primitive events that appear in the rule condition, including those appearing within the <not>
element, such as shown in the following example:
<condition>
<and equal="order.orderId, ship.orderId">
<object name="order"> Type = 'Gold' </object>
<not by="order.rlm$CrtTime+1"
join="order.Address_zipcode = ship.Address_zipcode">
<object name="ship"/>
</not>
</and>
</condition>
The rule condition with a negation is considered true only if the join condition in the <and>
element evaluates to true and the join condition in the not condition evaluates to false (or there is no event that matches this criteria within specified deadline).
In some applications, the primitive events that constitute a composite event can be the same structure. For example, AddItem
could be a primitive event that is generated when a customer adds an item to his shopping cart. Rules can be defined to monitor multiple items added to the shopping cart and suggest new items based on the past customer experiences (association rules generated by a data mining tools).
Consider an electronics Web store that sells accessories for camcorders. A typical rule in their application could be "If a customer adds a camcorder lens worth more than $100, a lens filter, and a IR light to the shopping cart, suggest a tripod to him". This rule consists of three simple conditions to be checked on every AddItem
event generated in the system, such as shown in the following example:
Accessory = 'Lens' and Price > 100 Accessory = 'Lens Filter' Accessory = 'IR Light'
To support the application described previously, the composite event structure can be modeled as an object type with multiple embedded types of the same primitive event type (AddItem
) as shown in the example that follows. If required, the same composite event structure may also include other primitive event types.
CREATE or REPLACE TYPE AddItem AS OBJECT ( Accessory VARCHAR(30), Make VARCHAR(20), Price NUMBER); CREATE or REPLACE TYPE CrossSellEvent AS OBJECT ( Item1 AddItem, Item2 AddItem, Item3 AddItem, Item4 AddItem, Item5 AddItem);
The preceding composite event is created to accommodate rules that are monitoring at most five primitive events in the shopping cart. (Note that the shopping cart may still contain more than 5 items.) In this rule application, the events can be configured for SESSION
duration (see Chapter3) such that only the primitive events generated within a user session are considered for rule matches. Using the composite event rule condition syntax, the preceding condition can be expressed as follows:
<condition> <and> <object name="Item1"> Accessory = 'Lens' and Price > 100 </object> <object name="Item2"> Accessory = 'Lens Filter' </object> <object name="Item3"> Accessory = 'IR Light' </object> </and> </condition>
Note that the element names Item1
, Item2
, and Item3
are used to assign the matching events to appropriate attributes of the CrossSellEvent
instance. Also, this assignment allows (join) predicates across primitive events in a rule condition as follows:
<condition>
<and join="Item1.Price+Item2.Price+Item3.Price > 300">
<object name="Item1"> Accessory = 'Lens' and Price > 100 </object>
<object name="Item2"> Accessory = 'Lens Filter' </object>
<object name="Item3"> Accessory = 'IR Light' </object>
</and>
</condition>
The examples discussed so far use rules that match all the primitive events specified in a rule condition. This is achieved with the use of an <and>
element as the parent of all the primitive event conditions. Some rule applications require rules that could match a subset of primitive events specified in the rule condition. For example, consider a composite event CE1
consisting of three primitive events PE1
, PE2
, and PE3
. Now, a rule condition defined for the composite event may need to match only one of the three primitive events. For this example, the composite event structure and the rule condition are represented as follows:
-- Composite event structure -- CREATE or REPLACE TYPE CE1 AS OBJECT ( pe1Inst PE1, pe2Inst PE2, pe3Inst PE3); -- Sample Rule condition -- <condition> <any> <object name="pe1Inst"/> <object name="pe2Inst"/> <object name="pe3Inst"/> </any> </condition>
When the rule condition should match any two of the three primitive events, the count
attribute of the <any>
element can be used, as shown in the example that follows. By default, the count
attribute has a value of 1, which is equivalent to a disjunction (OR) of all the primitive events specified within the <any>
element.
<condition> <any count=2> <object name="pe1Inst"/> <object name="pe2Inst"/> <object name="pe3Inst"/> </any> </condition>
The Any n semantics in the rule conditions are very common in applications using set semantics. The rule considered in the cross-selling application of Chapter4 can be extended to suggest the tripod to the customer if the shopping cart has any two of the three items specified. The condition for this rule can be represented using the Any n syntax as follows:
<condition>
<any count=2>
<object name="Item1"> Accessory = 'Lens' and Price > 100 </object>
<object name="Item2"> Accessory = 'Lens Filter' </object>
<object name="Item3"> Accessory = 'IR Light' </object>
</any>
</condition>
In a rule condition, some of the primitive events specified within an <any>
list may be mandatory for the condition to evaluate to true. For example, in the preceding rule condition, the Lens (Item1) may be mandatory and it should always count for one item in two items matched with the <any count=2>
specification. This new rule condition can be represented using the join attribute of the <any>
element as follows:
<condition>
<any count=2 join="Item1 IS NOT NULL">
<object name="Item1"> Accessory = 'Lens' and Price > 100 </object>
<object name="Item2"> Accessory = 'Lens Filter' </object>
<object name="Item3"> Accessory = 'IR Light' </object>
</any>
</condition>
Within an <any>
list, often there is a need to correlate the primitive events that occur. For example, the preceding rule can be extended to suggest the tripod to the customer only if the Make
attribute of the two items matched is same. When using an <and>
element (to match all three items), this can be posed as a join
predicate on the Make
attribute of each primitive event, such as shown in the following example:
<condition>
<and join="Item1.Make=Item2.Make and Item2.Make=Item3.Make">
<object name="Item1"> Accessory = 'Lens' and Price > 100 </object>
<object name="Item2"> Accessory = 'Lens Filter' </object>
<object name="Item3"> Accessory = 'IR Light' </object>
</any>
</condition>
However, similar join predicates cannot be used to correlate primitive events in an <any>
list because the missing primitive events (the one left out in 2 out of 3) are represented as NULLs and any predicate (other than IS NULL) on a NULL value is always false. For this purpose, when using the <any count=2>
specification, the rule should use the following join condition:
(Item1.Make is null and Item2.Make = Item3.Make) or (Item2.Make is null and Item1.Make = Item3.Make) or (Item3.Make is null and Item1.Make = Item2.Make)
Within an <any>
element, the preceding join condition can be represented in an abbreviated form using an equal clause. With this syntax, the join condition works well with any value assigned to the count attribute of the <any>
element, such as shown in the following example:
<condition>
<any count=2 equal="Item1.Make, Item2.Make, Item3.Make">
<object name="Item1"> Accessory = 'Lens' and Price > 100 </object>
<object name="Item2"> Accessory = 'Lens Filter' </object>
<object name="Item3"> Accessory = 'IR Light' </object>
</any>
</condition>
The equality joins among primitive events of a composite event are very common and thus this abbreviated syntax is supported for <and>
element as well, as shown in the following example:
<condition>
<and equal="Item1.Make, Item2.Make, Item3.Make">
<object name="Item1"> Accessory = 'Lens' and Price > 100 </object>
<object name="Item2"> Accessory = 'Lens Filter' </object>
<object name="Item3"> Accessory = 'IR Light' </object>
</condition>
When both equal
and join
attributes are used in an <and>
or an <any>
element, the join predicates represented by the equal specification are combined (using logical AND) with the join predicates listed with the join
attribute. For example, the following condition matches any two specified items which are of same make and whose total value is greater than 300. (Note the use of NVL functions in the join predicates).
<condition> <any count=2 equal="Item1.Make, Item2.Make, Item3.Make" join="NVL(Item1.Price,0) + NVL(Item2.Price,0) + NVL(Item3.Price,0) > 300"> <object name="Item1"> Accessory = 'Lens' and Price > 100 </object> <object name="Item2"> Accessory = 'Lens Filter' </object> <object name="Item3"> Accessory = 'IR Light' </object> </any> </condition>
The use of equal attribute at the rule class level (instead of each rule) is discussed in Chapter3.The sequence
attribute (Chapter4) can be used in an <any>
element to ensure that the matching primitive events happen in the specified order for the rule condition to evaluate to true.
<condition>
<any count=2 sequence="yes">
<object name="Item1"> Accessory = 'Lens' and Price > 100 </object>
<object name="Item2"> Accessory = 'Lens Filter' </object>
<object name="Item3"> Accessory = 'IR Light' </object>
</any>
</condition>
Footnote Legend
Footnote 1: For simplicity, the examples in this document are shown without the XML entity references for < (<
;), > (>
;), and '(&apos
;) symbols. Within a rule condition, less than is the only symbol that must be specified using an entity reference (<
;) or used within a XML CDATA section. Although it is not mandatory to use entity references for other symbols, they are recommended for compatibility reasons. Following the SQL naming convention, all the values specified for XML attributes and elements are case-insensitive. Case is preserved only if a value appears within quotes.