2010-05-18 4 views
2

쿼리 할 수 ​​있어야하는 타사에서 생성 한 여러 DBF 파일이 있습니다. 모든 열 유형이 문자로 정의 되었기 때문에 문제가 발생하지만 일부 필드의 데이터에는 실제로 이진 데이터가 포함되어 있습니다. 이 필드를 OleDbDataReader를 사용하여 문자열이나 문자 배열로 읽으려고하면 InvalidCastException이 발생하지만 이진 값으로 읽거나 적어도 읽었을 때 캐스팅/변환 할 수 있어야합니다. . 실제로 텍스트가 포함 된 열은 예상대로 반환됩니다.ADO.NET을 사용하여 잘못 정의 된 열 데이터 형식이있는 DBF 파일을 읽으려면 어떻게해야합니까?

예를 들어 첫 번째 열은 길이가 2 바이트 인 문자 필드로 정의되지만 필드는 16 비트 정수를 포함합니다.

다음 테스트 코드를 작성하여 첫 번째 열을 읽고 적절한 데이터 형식으로 변환했지만 값이 올바르게 나오지 않습니다.

데이터베이스의 첫 번째 행의 첫 번째 열에 17365 (0x43D5) 값이 있습니다. 다음 코드를 실행하면 끝나는 것은 17215 (0x433F)입니다. 데이터 판독기에서 반환 한 문자열에서 바이트를 가져 오기 위해 ASCII 인코딩을 사용해야한다는 확신이 있습니다. 그러나 필요한 형식으로 값을 가져 오는 또 다른 방법은 확실하지 않습니다. 내 자신의 DBF 리더를 작성하고 절대적으로해야하지 않는 한 내가하고 싶지 않은 ADO.NET을 모두 우회하십시오. 어떤 도움이라도 대단히 감사하겠습니다.

 byte[] c0; 
     int i0; 

     string con = @"Provider=Microsoft.Jet.OLEDB.4.0;Data Source=C:\ASTM;Extended Properties=dBASE III;User ID=Admin;Password=;"; 

     using (OleDbConnection c = new OleDbConnection(con)) 
     { 
      c.Open(); 
      OleDbCommand cmd = c.CreateCommand(); 
      cmd.CommandText = "SELECT * FROM astm2007"; 
      OleDbDataReader dr = cmd.ExecuteReader(); 
      while (dr.Read()) 
      { 
       c0 = Encoding.ASCII.GetBytes(dr.GetValue(0).ToString()); 

       i0 = BitConverter.ToInt16(c0, 0); 
      } 
      dr.Dispose(); 
     } 

답변

0

ASCII 문자 변환에 대해 정확하다고 확신합니다. 지원되는 스칼라 함수를 조금 보았습니다. 제트 엔진에 대한하지만 그들을 찾을 수 없습니다 ... 아니면 오히려 나는 스칼라 함수를 나열하지만 구문이 없습니다. CONVERT 기능은 아마도 원하는 것일 것입니다. 예 :

SELECT CONVERT(twobytefield, SQL_BINARY) from astm2007 

그런 다음 dr.GetBytes()으로 전화하여 원시 데이터를 읽을 수 있습니다. 그러나 Jet 엔진이 좋아하는 함수를 사용하여 명령문을 생성 할 수 없었습니다.

변환 작업을 수행 할 수없는 경우 Advantage .NET Data Provider을 사용하는 것이 좋습니다. 또는 OLE DB 공급자 (하지만 C#을 사용하고 있기 때문에 .NET 데이터 공급자가 더 적합 할 수 있습니다). 해당 제공자는 DBF 파일을 읽고 CONVERT 스. 라 함수를 지원합니다. 그것은 무료 로컬 엔진이 있습니다. 당신은 당신이 그것을 시도 가서 내가 거짓말을하지 않은 확인하기 위해 그것을 테스트하기 때문에하는 언급 때문에

, 여기 내가 사용하는 코드입니다 :

AdsConnection conn = new AdsConnection( 
    @"data source=c:\path;chartype=ansi;ServerType=local;TableType=cdx;"); 
conn.Open(); 
AdsCommand cmd = conn.CreateCommand(); 
cmd.CommandText = "select cast(somefield as sql_binary) from sometable"; 
cmd.CommandType = CommandType.Text; 
AdsExtendedReader rdr = cmd.ExecuteExtendedReader(); 
rdr.Read(); 
byte[] c0 = rdr.GetBytes(0); 
int i0 = BitConverter.ToInt16(c0, 0); 
Console.WriteLine("val = {0}", i0); 
+0

감사합니다. Advantage .NET 데이터 제공 업체에게 – figabytes

+0

을 줄 것입니다. @Jason : 전체 공개의 정신에서 Advantage 제품 라인의 개발자 중 한 명이라고 언급해야합니다. 그러나 로컬 엔진을 사용하는 데는 비용이 들지 않습니다. (잘하면 내 방식이 좋지는 않습니다.) 내가 그것을 테스트하는 데 사용되는 연결 문자열 정보로 답변을 업데이 트합니다. –

+0

그건 속임수 였어. 고마워요!BTW, 내가 그 부분에 어려움을 겪고 있었기 때문에 연결 문자열을 게시하게되어 기쁩니다. – figabytes

0

뭘로 실행중인 것은 사실 메모를 기반으로 필드입니다 ... 이러한 사실은 다른 파일 (일반적으로 .DBT (를 dBASE) 또는 .FPT (FoxPro에)에서 원시 텍스트가 열이 있습니다. 그것은 자유 형식의 길이이고 블록으로 쓰여지는 텍스트 내용 파일의 포인터 오프셋입니다. 그러나 포인터는 4 바이트로 저장됩니다.

.dbf 뷰어에 액세스 할 수 있고 다소 본질적으로 볼 수 있다면 아마도

+0

감사합니다,하지만이 필드는 메모 필드 아니다 . 그들은 이미지 파일에 바이트 오프셋 및 길이 정보를 포함하고 DBF 파일에 저장된 값이 정확한지 확인했습니다. – figabytes

관련 문제