У меня есть кусок SQL, который я хочу перевести в OCL. Я плохо разбираюсь в SQL, поэтому я хочу повысить удобство обслуживания. Мы используем Interbase 2009, Delphi 2007 с Bold и разработку на основе моделей. Теперь я надеюсь, что кто-то здесь хорошо говорит и на SQL, и на OCL :-) Исходный SQL:
Select Bold_Id, MessageId, ScaniaId, MessageType, MessageTime, Cancellation, ChassieNumber, UserFriendlyFormat, ReceivingOwner, Invalidated, InvalidationReason,
(Select Parcel.MCurrentStates From Parcel
Where ScaniaEdiSolMessage.ReceivingOwner = Parcel.Bold_Id) as ParcelState From ScaniaEdiSolMessage
Where MessageType = 'IFTMBP' and
not Exists (Select * From ScaniaEdiSolMessage EdiSolMsg
Where EdiSolMsg.ChassieNumber = ScaniaEdiSolMessage.ChassieNumber and EdiSolMsg.ShipFromFinland = ScaniaEdiSolMessage.ShipFromFinland and EdiSolMsg.MessageType = 'IFTMBF') and
invalidated = 0 Order By MessageTime desc
После небольшого упрощения:
Select Bold_Id, (Select Parcel.MCurrentStates From Parcel
where ScaniaEdiSolMessage.ReceivingOwner = Parcel.Bold_Id) From ScaniaEdiSolMessage
Where MessageType = 'IFTMBP' and not Exists (Select * From ScaniaEdiSolMessage
EdiSolMsg Where EdiSolMsg.ChassieNumber = ScaniaEdiSolMessage.ChassieNumber and
EdiSolMsg.ShipFromFinland = ScaniaEdiSolMessage.ShipFromFinland and
EdiSolMsg.MessageType = 'IFTMBF') and invalidated = 0
ПРИМЕЧАНИЕ. Существует 2 случая для MessageType: "IFTMBP" и "IFTMBF".
Таким образом, таблица, которая должна быть указана, — ScaniaEdiSolMessage. Он имеет такие атрибуты, как:
- Тип сообщения: Строка
- Номер шасси: строка
- ShipFromFinland: Boolean
- Недействительный: логическое значение
Он также имеет ссылку на таблицу Parcel с именем ReceiveOwner с BoldId в качестве ключа.
Таким образом, кажется, что он перечисляет все строки ScaniaEdiSolMessage, а затем имеет подзапрос, который также перечисляет все строки ScaniaEdiSolMessage и называет его EdiSolMsg. Затем он исключает почти все строки. На самом деле запрос выше дает одно попадание из 28000 записей.
В OCL легко перечислить все экземпляры:
ScaniaEdiSolMessage.allinstances
Также легко фильтровать строки, выбирая, например:
ScaniaEdiSolMessage.allinstances->select(shipFromFinland and not invalidated)
Но я не понимаю, как мне сделать OCL, чтобы он соответствовал приведенному выше SQL.