I have a simple order, order_items, order_status schema:
As can be seen, and order can have several order_items. Each order_item have two (Boolean) fields, checked_in and verified.
The status of an order takes the values, ORDERED, RECEIVING, RECEIVED and CANCELED.
After checking in, or verifying an order_item, I want to create a database trigger (on the order_items table), that queries the values for the checked_in and verified fields, for each order_item.
If none of the fields are set, the order status is 'ORDERED'. If all fields are set, the order status is 'RECEIVED'. If anything in between, the order status is 'RECEIVING'.
Currently the status is set 'manually', by running the following query
SELECT oi.checked_in, oi.verified
FROM order_items AS oi
WHERE order_id = 54;
Which yields a result like this:
The full code looks like this:
dsl_shared_ptr<TSQLQuery> q(new TSQLQuery(NULL));
q->SQLConnection = LITDBConnectionDM->SQLConnection1;
int orderID = OrdersCDS->FieldByName("id")->AsInteger;
stringstream query;
query <<
"\
SELECT oi.checked_in, oi.verified \
FROM order_items AS oi \
WHERE order_id = :oID";
q->SQL->Add(query.str().c_str());
q->Params->ParamByName("oID")->AsInteger = orderID;
q->Open();
q->First();
int checkedInCount(0);
int verifiedCount(0);
int recordCount(0);
if(!q->IsEmpty())
{
while(!q->Eof)
{
recordCount++;
if(q->FieldByName("checked_in") && q->FieldByName("checked_in")->AsInteger)
{
checkedInCount++;
}
if(q->FieldByName("verified") && q->FieldByName("verified")->AsInteger)
{
verifiedCount++;
}
q->Next();
}
}
string orderStatus("");
if(checkedInCount == 0 && verifiedCount == 0)
{
orderStatus = "ORDERED";
}
else if(checkedInCount == verifiedCount && checkedInCount == recordCount)
{
orderStatus = "RECEIVED";
}
else
{
orderStatus = "RECEIVING";
}
int order_status = getIDForOrderStatus(orderStatus);
OrdersCDS->Edit();
OrdersCDS->FieldByName("status")->AsInteger = order_status;
OrdersCDS->Post();
OrdersCDS->ApplyUpdates(0);
As can be seen, I'm 'manually' deducing the order status by checking the verified, checked_in flags, for each order_item.
How can the above be achieved in a SQL query inside a trigger?


Basically I think the
updatequery you want to write is:The logic is to aggregate the order items; we can decide which status should be assigned to the order by looking at the
min()andmax()of the addition of the two statuses of each item. We then bring thestatustable to translate the description of the status into the relevant primary key value.Note that storing this information is not necessarily a good idea. Extra effort is required to keep the information up to date when the statuses of order items change (or when new items are added to an order, if that's possible in your use case).
Starting from the above query, you could very well create a view, that computes the information on the fly whenever queried.