Q&A

  • dbexpress error: Invalid field type 오류...
DB는 오라클 9i 입니다. 클라이언트도 9i입니다.
프로그램은 Delphi 7/Kylix3에서 사용하고 기본 코딩은 delphi7에서 합니다.
원래 프로그램은 아래에 있는 주석 부분으로 처리하였는데 잘 되더군요.
다만 시간이 너무 걸리는 관계로...
약 500건 전후의 행을 저장하는데 2분정도 걸립니다.
쿼리가 저장할 때마다 바뀌어 그런가하고 동일 쿼리에 파라미터를 변경하는 형태로 바꾸었습니다.(쿼리 재사용을 위해서...)
그랬더니 실행할 때 오류가 발생합니다. dbexpress error: Invalid Field type
왜 그럴까요? 이리저리 테스트를 해보았지만 일주일째 헤매고 있습니다.
굳이 이 형태가 아니어도 속도를 개선할 방법을 알수 있을까요?
윈도와 리눅스에서 동시에 작동하여야 합니다.

  // 해당 Layer의 셀 정보를 DB에 저장
  // 입력 => LL : layer, Cel : 셀 수, Wei : 셀당 필드의 수.
  // DB => mazacell (id, layer, cell, /* 이상 number(12) */
                              w00, w01, w02, ..., w45) /* float */
  //          primary key (id, layer, cell)
  // 전역변수 Col[] : 칼럼 이름을 저장한 스트링 배열
  // 전역변수 FLife[i].Dna[,,] : 저장될 float형 자료를 가진 배열
  // 전역변수 TempStr : 임시로 사용하는 문자열.
  // 전역변수 Qry2 : TSqlQuery instance. SQLConnection에 연결되었음.
  procedure LayerUpdate(LL, Cel, Wei : integer);
  var
    j, k : integer;
  begin
//    for j := 0 to Cel -1 do begin
//      // update 쿼리문자열 구성. w00=0.12317 형태로.
//      TempStr2 := format('%s=%g',[Col[0], FLife[i].Dna[LL,j,0]]);
//      for k := 1 to Wei -1 do
//        TempStr2 := TempStr2 + format(',%s=%g',[Col[k], FLife[i].Dna[LL,j,k]]);
//      Qry2.SQl.Clear;
//      Qry2.SQL.Add('update mazacell set '
//                     + TempStr2
//                     + ' where '
//                     + 'id = ' + IntToStr(FLife[i].id) + ' and '
//                     + 'layer = ' + IntToStr(LL) + ' and '
//                     + 'cell = ' + IntToStr(j));
//      Qry2.ExecSQL(true);
//      end;
//------- test for speed up.
    // update 쿼리문자열 구성. w00=:w00 형태로.
    TempStr2 := Col[0] + '=:' + Col[0];
    for k := 1 to Wei -1 do
      TempStr2 := TempStr2 + ',' + Col[k] + '=:' + Col[k];
    Qry2.Sql.Clear;
    Qry2.Params.Clear;
    Qry2.Sql.Add('update mazacell set ' + TempStr2
        + ' where id=:id and layer=:layer and cell=:cell');
    // 파라미터 생성
    for k := 0 to Wei -1 do
      Qry2.Params.CreateParam(ftFloat, Col[k], ptInput);
    Qry2.Params.CreateParam(ftInteger, 'ID', ptInput);
    Qry2.Params.CreateParam(ftInteger, 'Layer', ptInput);
    Qry2.Params.CreateParam(ftinteger, 'Cell', ptInput);
    // 각 cell 별로 파라미터를 저장하고 쿼리 실행.
    for j := 0 to cel -1 do begin
      for k := 0 to Wei -1 do
        Qry2.Params[k].AsFloat := FLife[i].Dna[LL,j,k];
      Qry2.Params[Wei].AsInteger := FLife[i].id;
      Qry2.Params[Wei +1].AsInteger := LL;
      Qry2.Params[Wei +2].AsInteger := j;
      Qry2.ExecSQL(false);
      end;
//------- test end.
  end;
1  COMMENTS
  • Profile
    류해곤 2004.11.02 03:14
    자문자답이 되었군요.
    파라미터 타입을 다른 형태로 바꾸어서 적용 시켰습니다.

    float - float => BCD - currency
    integer - integer => string - string

    http://podgoretsky.com/ftp/Docs/DB/QGDBE/quickguide_dbexpress.htm
    에서 참조 했습니다.
    약 20초 정도 개선 효과가 있네요. 기대한 만큼은 못미치지만...
    좀 더 나은 방법이 있으면 알려주세요. 시험용 자료는 500건 정도이지만
    실제 적용할 자료는 50만건 정도인지라...

       ...<전략>
        Qry2.Params.Clear;
        Qry2.Sql.Add('update mazacell set ' + TempStr2
            + ' where id=:id and layer=:layer and cell=:cell');
    // 파라미터를 생성하면 실제 파라미터의 수가 2배가 되었음.
    // 아마 params.clean의 위치와 관련이 있지 않을까 추정. test 않음.
    //    // 파라미터 생성
    //    for k := 0 to Wei -1 do
    //      Qry2.Params.CreateParam(ftBCD, Col[k], ptInput);
    //    Qry2.Params.CreateParam(ftString, 'ID', ptInput);
    //    Qry2.Params.CreateParam(ftString, 'Layer', ptInput);
    //    Qry2.Params.CreateParam(ftString, 'Cell', ptInput);
        for j := 0 to cel -1 do begin
          for k := 0 to Wei -1 do
    //        Qry2.Params[k].AsFloat := FLife[i].Dna[LL,j,k];
            Qry2.Params[k].AsBCD := StrToCurr(VarToStr(FLife[i].Dna[LL,j,k]));
    //     Qry2.Params[Wei].AsInteger := FLife[i].id;
    //     Qry2.Params[Wei +1].AsInteger := LL;
    //     Qry2.Params[Wei +2].AsInteger := j;
          Qry2.Params[Wei].AsString := IntToStr(FLife[i].id);
          Qry2.Params[Wei +1].AsString := IntToStr(LL);
          Qry2.Params[Wei +2].AsString := IntToStr(j);
          Qry2.ExecSQL(false);
          end;