2016-07-26 2 views
1

가 나는 BC에있는 모든 레코드를 반복하고, 그들 중 일부 삭제해야하는 비즈니스 서비스 쓰고 있어요 그러나루프에서 레코드를 삭제하려면 어떻게해야합니까?

bc.ExecuteQuery(ForwardBackward); 
var isRecord = bc.FirstRecord(); 
while (isRecord) { 
    if (...) { 
    bc.DeleteRecord(); 
    } 
    isRecord = bc.NextRecord(); 
} 

, DeleteRecord moves the cursor to the next one를, 그래서 각각의 존재에 대한 기록을 건너 뛰는 것 삭제되었는데, 이는 내가 원하는 것이 아닙니다. 어떤 표준이 있습니까? ish이 문제를 해결할 방법이 있습니까?

나는 수표 하나와 삭제를위한 두 개의 루프를 만들 수 있다고 생각하는데 ... 작동하지만 레코드보다 두 번 반복하는 것이 어리석은 느낌이 든다. 이보다 더 좋은 방법이 있어야한다. :

bc.ExecuteQuery(ForwardBackward); 
var isRecord = bc.FirstRecord(); 
var list = []; 
while (isRecord) { 
    if (...) { 
    list.push(bc.GetFieldValue("Id")); 
    } 
    isRecord = bc.NextRecord(); 
} 

bc.ClearToQuery(); 
bc.SetSearchSpec("Id", "='" + list.join("' OR ='") + "'"); // "='1-ABCD' OR ='1-1234'" 
bc.ExecuteQuery(ForwardBackward); 
while (bc.FirstRecord()) { 
    bc.DeleteRecord(); 
} 
+1

문제는 DeleteRecord는 반환하지 않는다는 것입니다 아무것도. 그렇지 않으면 논리는 if 루프로 쉽게 재 배열 될 수있었습니다. 목록으로 이동하고 선택적으로 삭제하는 논리는 최적화 된 모양입니다. –

답변

1

솔루션은 경우 (...) 조건에 직접적으로 의존한다 :

  • 을가 검색 표현으로 변환 할 수있는 간단한 조건의 경우에, 당신은 단지 수 검색어를 만들고 모든 것을 삭제하십시오. 발견 된

  • 검색 조건으로 구현할 수없는 복잡한 조건 인 경우 다음 두 가지 방법으로 수행 할 수 있습니다. 둘 다 자체 단점이 있습니다. a) DeleteRecord와 PreviousRecord를 어색하게 조합하십시오. 그

    function deleteRecord(sId:chars) { 
        ... 
        bc.SetSearchSpec("Id", sId); 
        bc.ExecuteQuery(ForwardOnly); 
        if (bc.FirstRecord()) { 
        bc.DeleteRecord(); 
        } 
    } 
    ... 
    bc.ExecuteQuery(ForwardBackward); 
    var isRecord = bc.FirstRecord(); 
    while (isRecord) { 
        if (...) { 
        deleteRecord(bc.GetFieldValue("Id")); 
        } 
        isRecord = bc.NextRecord(); 
    } 
    ... 
    
  • 같은 b)는 하나의 레코드를 삭제하고 조건을 만족하는 각 레코드에 대해 호출됩니다 두 번째 방법을 만들고, 뭔가

귀하의 솔루션이 될 및 옵션 C),하지만 때 작동하지 않습니다 수 있습니다 ID 목록은 너무 커서 쿼리가 거대한 SQL 문으로 이어지며 데이터베이스에 SQL 쿼리 크기에 대한 일부 제한이 있으며 DBA는 이러한 쿼리를 로그에서 볼 수 없으므로 ID 목록이 너무 커집니다.

나는 b) 옵션을 선호합니다. 메인 함수에서 동일한 BC의 두 번째 인스턴스를 생성하여이를 최적화하고 deleteRecord 함수를 참조하여 전달할 수 있습니다.

+0

이 특별한 escenario에서는 조건이 매우 간단했습니다. "while FirstRecord, DeleteRecord"라는 검색 스펙으로 이동했습니다. 나는 다른 사람들이 복잡한 사건에서 그것을 어떻게하는지 알아내는 데 더 관심이있었습니다. 나는 당신의 b) 옵션도 선호한다고 생각합니다. 더 깨끗합니다. – AJPerez

0

첫 번째 레코드의 값을 var에 저장 한 다음 루프에서 레코드가 있는지 확인합니다. 나는 당신이 앞으로 나아갈 것을 제안한다. var 값이 증가합니다. 따라서 while 루프 내부에서 요소 명령을 뒤로 이동하면 var에 이전 요소가 저장됩니다. 루프를 실행 한 후 다음 요소로 쉽게 증가시킬 수 있습니다.

bc.ExecuteQuery(ForwardBackward); 
var isRecord = bc.FirstRecord(); 
while (isRecord) { 
    if (...) { 
    bc.DeleteRecord(); 
    bc.PreviousRecord(); 
    } 
    isRecord = bc.NextRecord(); 
} 

을하거나 뒤로 루프를 수행합니다 :

+1

pls는 몇 가지 예를 제공합니다. – JayKandari

1

당신이 ForwardBackward을하고 있기 때문에, 당신은 단지 삭제 후 PreviousRecord 전화를 추가 할 수

bc.ExecuteQuery(ForwardBackward); 
var isRecord = bc.LastRecord(); 
while (isRecord) { 
    if (...) { 
    bc.DeleteRecord(); 
    } 
    isRecord = bc.PreviousRecord(); 
} 
+0

확실히 두 번째가 더 좋습니다. 그러나 두 레코드 모두에 문제가 있습니다. "마지막 레코드에서 DeleteRecord 메서드를 사용하면 커서는 아무 것도 가리 키지 않습니다." 거기에서 PreviousRecord를 할 수 있는지 확실하지 않습니다. – AJPerez

+0

@AJPerez'PreviousRecord'가 작동하지 않더라도'NextRecord'가 거짓을 반환 할 것이기 때문에 첫 번째 문제는 그다지 문제가되지 않을 것입니다. 하지만 그렇습니다. 시벨 BC는'DeleteRecord()'를 반환하거나 GetCurrent() 메소드를 사용하는 것이 좋습니다. – Jcl

+0

나는 당신이 옳을 수도 있다고 생각했기 때문에 그냥 시도해 봤습니다 ...하지만 이상한 것 일어납니다 : D. 예를 들어 BC에 4 개의 레코드가 있고 두 번째 코드를 실행하면 (if가없는 경우) 4 번째를 삭제하고 3을 건너 뛰고 2와 1을 삭제합니다. 이전에 이전 레코드를 삭제할 때 이전 레코드를 호출하지 않습니다. 너무 잘 작동하는 것 같습니다. 첫 번째 코드는 요소 중 하나를 건너 뜁니다.이 경우에는 어느 요소가 건너 뛴 것인지 또는 건너 뛴 것인지를 확인하지 않았습니다. – AJPerez

관련 문제