2012-02-15 1 views
2

InterBase 4.2.1로 만든 일부 이전 데이터베이스 데이터베이스 파일에서 데이터를 추출해야합니다. Firebird의 임베디드 버전 (버전 2.5.1)과 .NetProvider (버전 2.7.0)를 사용하고 있습니다. 전에는 파이어 버드의 interbase로 일한 적도 없지만 (SQL SERVER와 SQLite에 대한 경험이 있습니다.) 웹을 크루징하고 2 일 동안 실험 한 후에도 아직 해결책을 찾지 못했습니다.올바른 문자 인코딩을 감지 할 수 없습니다.

데이터베이스의 테이블에는 영어로 된 데이터뿐만 아니라 히브리어의 데이터도 포함됩니다. I이었다 낙관적으로, 나는 UTF8을 사용하여 내 연결 문자열을 작성하여 시작 :

FbConnectionStringBuilder builder = new FbConnectionStringBuilder(); 
builder.Database = m_DatabaseName; 
builder.ServerType = FbServerType.Embedded; 
builder.Charset = FbCharset.Utf8.ToString(); 

를하지만 나에게 다음과 같은 예외 주었다

bad parameters on attach or create database 
CHARACTER SET Utf8 is not defined 

내가 제대로 fbintl.dll을 사용합니다. (아래의 내 응용 프로그램 디렉토리 및 하위 디렉토리에있는 파일 참조). 심지어 ProcessMonitor를 사용하여 fbintl.dll이로드되었는지 확인했습니다.

fbembed.dll 
firebird.log 
firebird.msg 
FirebirdSql.Data.FirebirdClient.dll 
ib_util.dll 
icudt30.dll 
icuin30.dll 
icuuc30.dll 
MyApplication.exe 
Microsoft.VC80.CRT.manifest 
msvcp80.dll 
msvcr80.dll 
intl\fbintl.conf 
intl\fbintl.dll 
udf\fbudf.dll 
udf\ib_udf.dll 

그래서 나는 더 많은 이들의 절반 이상, FbCharset을 열거하고 각 문자 집합에 연결하려는 시도 같은 예외를 던져, 나는 다른 사람들과 연결 (IDataReader.GetString()를 사용하여) 히브리어 필드 중 하나를 조회 할 때 , 나는 항상 같은 쓰레기를 결과로 얻었다. 연결 문자열에 어떤 문자 집합을 지정해야하는지는 중요하지 않습니다. 문자 집합을 전혀 지정하지 않아도 결과는 항상 동일합니다.

다음은 데이터베이스 SELECT RDB$CHARACTER_SET_NAME FROM RDB$CHARACTER_SETS에 정의 된 문자 집합을 쿼리하고 그 중 하나와 연결하려고 시도한 일부를 예외 처리했으며 나머지는 이전과 동일한 결과를 제공했습니다.

데이터베이스가 생성 된 문자 집합에 대한 단서가 없지만 데이터베이스의 각 필드에있는 문자 집합을 검사하고 모든 텍스트 필드의 문자 집합이 '없음'으로 설정되어 있습니다.

SELECT r.RDB$RELATION_NAME, r.RDB$FIELD_NAME, f.RDB$FIELD_NAME, cset.RDB$CHARACTER_SET_NAME 
FROM RDB$RELATION_FIELDS r 
LEFT JOIN RDB$FIELDS f ON r.RDB$FIELD_SOURCE = f.RDB$FIELD_NAME 
LEFT JOIN RDB$CHARACTER_SETS cset ON f.RDB$CHARACTER_SET_ID = cset.RDB$CHARACTER_SET_ID 
ORDER BY r.RDB$RELATION_NAME ASC, r.RDB$FIELD_POSITION ASC 

하지만 시스템 테이블의 텍스트 필드 중 일부가 문자 세트로 UNICODE_FSS를 가지고있는 것으로 나타났습니다. 이미 연결 문자열에서 해당 문자 집합을 시도했지만 요청한 텍스트 필드에 여전히 garbadge가 표시됩니다.

내 마지막 시도는 자신을 (IDataReader.GetBytes()를 사용하여) 바이트를 검색하고 문자열을 인코딩하는 것이 었습니다, 그러나 이것은 나에게 캐스트 예외를 제공합니다 (Unable to cast object of type 'System.String' to type 'System.Byte[]'.)

사람이 데이터를 읽는 방법에 어떤 아이디어가 있습니까? 데이터베이스를 영구적으로 변환 할 필요가 없습니다. 데이터를 추출한 후에는 더 이상 사용하지 않습니다.

EDIT : btw, 무료 가벼운 interbase/firebird 데이터베이스 뷰어가 있습니까? 어떤 좋은 파일도 찾을 수없는 것 같습니다 (SQLiteSpy과 유사)?

마크

+1

http://gsbelarus.com/gs/fdbconvert/ FDBConvert 유틸리티를 사용하여 데이터베이스를 FB 2.5 형식으로 변환하십시오. –

+0

고마워, 방금 해봤는데 "알 수없는 서버 유형"오류가 발생했다. FBClone 유틸리티 (http://code.google.com/p/fbclone/, 버전 2.1.4)를 사용해 보았습니다. 내 데이터베이스에이 기능이없는 것처럼 작동하지 않았습니다. RDB $ FIELDS.RDB $ FIELD_PRECISION. 나는이 데이터베이스를 만들기 위해 사용 된 데이터베이스 버전이이 유틸리티들에 비해 너무 오래되었다고 생각한다. – Marc

+0

관심이 있으시면 IB 4.2 설치가 있습니다. 더 나은 방법은 FB 1.0 버전까지 백업 및 복원 시퀀스를 통해 데이터베이스를 업그레이드 한 다음 FDBConvert 유틸리티를 사용하여 2.5로 변환하는 것입니다. –

답변

3

해결책을 찾았습니다.

원본 데이터베이스는 코드 페이지 1255가있는 Windows에 작성되었습니다. 지금 데이터를 읽을 때 C#은 기본 인코딩 (1255가 아님)을 사용하여 유니 코드 문자열을 생성합니다. 그래서 난 그냥 기본 인코딩을 사용하여 바이트 문자열을 디코딩하고 올바른 인코딩을 사용하여 문자열을 바이트로 변환합니다.

Encoding encoding = Encoding.GetEncoding(1255); 
... 
if (!datareader.IsDBNull(i)) 
{ 
    string value = dataReader.GetString(i); 
    if (value.Length > 0) 
    { 
     byte[] bytes = Encoding.Default.GetBytes(value); 
     value = encoding.GetString(bytes); 
    } 
    // store value 
} 

이 솔루션은 나를 위해 잘 작동하지만 예외 bad parameters on attach or create database - CHARACTER SET WIN1255 is not defined을받지 않고 내 ConnectionString을의 캐릭터 세트로 "WIN1255"를 지정할 수없는 이유를 난 아직도 이해가 안 돼요? (나는 심지어 문자셋 "WINDOWS1255"를 시도했지만 예외는 Invalid character set specified이다.).