3

OCL に変換したい SQL があります。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

: MessageType には、'IFTMBP' と 'IFTMBF' の 2 つのケースがあります。

したがって、リストされるテーブルは ScaniaEdiSolMessage です。次のような属性があります。

  • MessageType: 文字列
  • ChassiNumber: 文字列
  • ShipFromFinland: ブール値
  • 無効: ブール値

また、BoldId をキーとして RecomingOwner という名前のテーブル Parcel へのリンクもあります。

そのため、ScaniaEdiSolMessage のすべての行を一覧表示し、さらに ScaniaEdiSolMessage のすべての行を一覧表示して EdiSolMsg という名前のサブクエリを持っているようです。次に、ほぼすべての行を除外します。実際、上記のクエリは 28000 レコードから 1 つのヒットを返します。

OCL では、すべてのインスタンスを簡単にリストできます。

ScaniaEdiSolMessage.allinstances

たとえば、選択して行を簡単にフィルタリングすることもできます。

ScaniaEdiSolMessage.allinstances->select(shipFromFinland and not invalidated)

しかし、上記の SQL に一致する OCL を作成する方法がわかりません。

4

3 に答える 3

3

Gabriel と Stephanie の話を聞いて、SQL について学びましょう。

あなたはコードをより保守しやすいものにしたいと述べていますが、SQL を理解している開発者の数は、OCL を理解している開発者の数よりもはるかに多くなっています。

これを OCL に変換した後、明日プロジェクトを離れると、OCL を維持できる人を見つけることができる可能性は非常に低くなります。ただし、SQL を保守する人を見つける可能性は非常に高くなります。

丸いハンマーが得意だからといって、丸い穴に四角いペグをはめようとしないでください:)

于 2011-01-24T13:16:09.500 に答える
1

あなたを助けるかもしれないプロジェクト、ドレスデンOCLがあります。

Dresden OCLは、UML、EMF、JavaなどのさまざまなモデルのOCL制約を解析および評価するための一連のツールを提供します。さらに、ドレスデンOCLは、Java/AspectJおよびSQLコード生成用のツールを提供します。Dresden OCLのツールは、他のプロジェクトのライブラリとして、またはEclipseをOCLサポートで拡張するプラグインプロジェクトとして使用できます。

私はそれを使用していませんが、ツールがモデルとOCL制約からSQLを生成する方法を示すデモがあります。私はあなたが反対を求めていることを理解しています、しかし多分これを使ってあなたはそれを理解することができます。同じ人々によるOCL->SQL変換について説明している論文もあります。

于 2012-09-13T22:03:41.620 に答える
0

MDriven (Bold for Delphi の後継) を使用すると、次のようになります。

OCL to SQL を使用する場合、チェックする必要があるさまざまな情報セットについて考えれば、すべてが簡単になります。次に、ocl 演算子を ->intersection として使用して、目的のセットを見つけます。

したがって、あなたの場合、次のようなセットがあるかもしれません:

ScaniaEdiSolMessage.allinstances->select(shipFromFinland and not invalidated)

しかし、次のようなセットもあります。

ScaniaEdiSolMessage.allinstances->select(m|m.ReceivingOwner.MessageType = 'IFTMBP')

さらに、次の基準があります。

Parcel.allinstances->select(p|p.Messages->exists(m|m.MessageType = 'IFTMBF')).Messages

これらのセットがすべて同じ結果タイプ (ScaniaEdiSolMessage のコレクション) を持っている場合は、単純にそれらを交差させて目的の結果を得ることができます

ScaniaEdiSolMessage.allinstances->select(shipFromFinland and not invalidated)
->intersection(ScaniaEdiSolMessage.allinstances->select(m|m.ReceivingOwner.MessageType = 'IFTMBP'))
->intersection(Parcel.allinstances->select(p|p.Messages->exists(m|m.MessageType = 'IFTMBF')).Messages
    )

そして、それを見て、次のように少し減らすことができます:

    ScaniaEdiSolMessage.allinstances
    ->select(m|m.shipFromFinland and (not m.invalidated) and
              (m.ReceivingOwner.MessageType = 'IFTMBP'))
    ->intersection(Parcel.allinstances->select(p|
             p.Messages->exists(m|m.MessageType = 'IFTMBF')).Messages
        )
于 2017-12-27T08:50:55.957 に答える