2010-06-10 5 views
3

OCL로 변환하려는 SQL 부분이 있습니다. 나는 SQL이 좋지 않아서 이것으로 유지 보수성을 높이고 싶다. 우리는 Interbase 2009, Delphi 2007을 대담하고 모델이 적용된 개발과 함께 사용하고 있습니다.SQL을 OCL로 변환 하시겠습니까?

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 

참고 : 작은 단순화 후

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 

: 이제 내 희망은 여기에 두 사람이 :-) 원래 SQL 좋은 SQL과 OCL을 말하는 것입니다 메세지 유형 2 가지 경우가 있습니다 , 'IFTMBP'및 'IFTMBF'로 구성됩니다.

그래서 나열 할 테이블은 ScaniaEdiSolMessage입니다.

  • 메세지 유형 : 문자열
  • ChassiNumber : 문자열
  • ShipFromFinland : 부울
  • 무효화 : 이 같은 속성이 부울을

또한 함께 ReceivingOwner라는 이름의 테이블 소포에 대한 링크가 키로 굵게 표시.

그래서 ScaniaEdiSolMessage의 모든 행을 나열한 다음 ScaniaEdiSolMessage의 모든 행을 나열하고 EdiSolMsg라는 이름의 하위 쿼리가있는 것처럼 보입니다. 그런 다음 거의 모든 행을 제외합니다. 실제로 위의 쿼리는 28000 개의 레코드에서 한 번의 히트를 제공합니다.

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

하지만 난에 OCL을하는 방법을 이해하지 않습니다

또한
ScaniaEdiSolMessage.allinstances 

쉽게 예를 들어 선택에 의해 행을 필터링 :

OCL에서는 모든 인스턴스를 나열하기 쉽다 위의 SQL과 일치하십시오.

+4

당신은 어떤 스카니아 트럭 물건을하고있다 :) 은 무엇 당신이 원하는 것은없는 것 같다 : 그들은 우리가 그것을 비트를 줄일 수 있다는보고

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 ) 

그리고이 원하는 결과를 얻을 수 있습니다 그래서 나에게 잘해. 우선 SQL은 객체 지향 환경에서 1 차 술어에 대한 관계 대수와 OCL을 기반으로합니다. 이것은 그들로 하여금 세상을 다른 시각으로 바라 보게합니다. 예 : SQL에서의 간단한 탐색은 선택 및 결합에 관한 것입니다. OCL에서는 한 객체에서 다른 객체로의 연결을 수행합니다. 개체 지향 및 관계형 불일치로 인해 앞으로 많은 문제가 발생할 수 있습니다. –

+0

예, 응용 프로그램에 일부 트럭이 있습니다. 많은 SQL 표현식이 객체 지향적이라 할지라도 OCL로 변환하기가 상대적으로 쉽습니다 (OCL은 사물을 필터링 할 수도 있음). 어떤 종류의 불일치 문제를 생각하고 있는지 알 수는 없지만 OCL에서는 가능한 한 많이 원합니다. –

+2

당신이 가지고있는 것을 유지하기 위해 적어도 충분한 SQL을 배우지 않겠습니까? 나는 가브리엘에 동의한다. 또는 SQL 대신 OCL을 사용하는 데이터베이스를 찾을 수도 있습니다. –

답변

3

가브리엘과 스테파니의 말을 듣고 더 많은 SQL 정보를 얻으십시오.

코드를 좀 더 유지 보수하기 쉽도록 작성했지만 SQL을 이해하는 개발자의 수는 OCL을 이해하는 개발자의 수보다 훨씬 많습니다.

OCL로 변환 한 후 내일 프로젝트를 종료하면 OCL을 유지 관리 할 수있는 사람을 찾을 가능성이 매우 낮습니다. 그러나 SQL을 유지할 수있는 사람을 찾을 수있는 기회는 매우 높습니다.

는 라운드 망치 :

+0

글쎄 그건 단지 선호 사항 일뿐입니다. 가능한 경우 OCL을 사용하는 정책이 있습니다. OCL을 사용하는 이유는 간단하며 프레임 워크를 벗어난 Bold의 토대입니다. 그러나 나는 OCL보다 SQL을 더 많이 알고 있다는 것에 동의한다. –

1

프로젝트가있다, Dresden OCL, 당신이 도움이 될 잘하고해서 둥근 구멍에 스퀘어 페그에 맞게하지 마십시오.

Dresden OCL은 UML, EMF 및 Java와 같은 다양한 모델에서 OCL 제약 조건을 구문 분석하고 평가할 수있는 도구 세트를 제공합니다. 또한 Dresden OCL은 Java/AspectJ 및 SQL 코드 생성을위한 도구를 제공합니다. Dresden OCL 도구는 다른 프로젝트의 라이브러리로 사용하거나 OCL 지원으로 Eclipse를 확장하는 플러그인 프로젝트로 사용할 수 있습니다.

필자는 사용하지 않았지만 도구가 모델 및 OCL 제약 조건에서 SQL을 생성하는 방법을 보여주는 demo이 있습니다. 나는 당신이 반대를 요구하고 있다는 것을 깨닫고 있지만, 이것을 사용하면 어쩌면 알아낼 수 있습니다. 동일한 사람들에 의한 OCL-> SQL 변환을 설명하는 paper도 있습니다.

0

MDriven 내가 이런 식으로 할 것 (델파이 굵게의 후계자) :

당신이 확인해야 할 다른 세트의 정보를 생각해 보면 모든 것이 쉬워진다 SQL로 OCL 작업 - 사용 후 및 ocl 연산자를 -> 교차로로 설정하면 찾으려는 설정을 찾습니다.

그래서 귀하의 경우에는이 같은 설정이있을 수 있습니다

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(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 
     ) 
+1

allinstances는 OCL 기능이 아닙니다. 아마 allInstances() –

+0

Bold은 OCL 표준을 엄격하게 따르지 않을 수도 있으므로 allinstances가 실제로 올바르게 작동합니다. 이 질문은 7 살 이상입니다. 코드의 빠른 확인은 원본 SQL이 동일 함을 보여줍니다. –

+0

@EdWillink - 당신이 맞습니다 - OCL 괄호 안에는 메소드가 인수를 취하지 않더라도 필수입니다. 그러나 OCL의 MDriven 구현에서는 매개 변수가 없을 때 생략 할 수 있습니다. –