2009-07-22 4 views
2

우리는 데이터를 데이터베이스에 저장하는 독립 실행 형 응용 프로그램을 개발 중입니다. 우리는 데이터베이스와의 통신을 위해 Dataset과 TableAdapters를 사용합니다. 기본적인 요구 사항 중 하나는 SQL Server, Oracle 및 MySQL을 사용할 수있는 응용 프로그램입니다. 이를 위해 TAs 벤더 독립적 인 쿼리를 작성했습니다. 우리는 ODBC 공급자를 사용합니다.Oracle NUMBER 문제 : Decimal에서 Int64로 캐스트

SQL Server와 MySQL에는 잘 작동하지만 오라클에는 문제가있었습니다. 우리가 극복 할 수없는 문제 중 하나는 십진수에서 Int64 로의 캐스팅 오류입니다.

오라클 테이블은 10 진수로 매핑 된 시스템 ID (자동 증가 필드)에 NUMBER (38)을 사용합니다. 그러나 SQL Server와 MySQL은 BIGINT를 사용하기 때문에 DataSet/TA에서 Int64/long을 사용합니다. (DataSEt TableAdapters는 처음부터 SQL Server 스키마에서 자동으로 생성됩니다.)

10 진수 개체를 반환하기 때문에 Oracle에서 NUMBER 값을 가져올 때 캐스트 예외가 발생합니다.

DbCommand getIDcmd = connection.CreateCommand(); 
getIDcmd.CommandText = "select LAST_ID from SEQUENCE_ID"; 
sequenceID = (Int64)getIDcmd.ExecuteScalar(); // we get a cast exception here returns decimal 

우리가 다른 포럼 항목이 있지만 운 보았 듯이 오라클 정밀 번호 (예를 들어, 번호 (10)) 낮은 시도한 점에 유의하시기 바랍니다.

이 문제가 ODBC입니까? 우리가 다른 공급자로 이동하면 문제가 해결 될까요?

답변

1

sequence_id이 시퀀스 이름 인 경우 Oracle에서 쿼리가 올바르게 보이지 않습니다. 당신은 같은 쿼리와 함께 지난 주어진 ID를 조회 할 것이다 :

SELECT last_number FROM all_sequences WHERE sequence_owner=? AND sequence_name=? 

캐스팅 문제가되지 않습니다 (INT64 범위 내 경우)를.

1

당신은 실제로 반환되는 어떤 종류를 확인하려면이 옵션을 실행 한 다음 거기에서 갈 수 :

System.Windows.Forms.MessageBox.Show(getIDcmd.ExecuteScalar().GetType().ToString()); 
1

그것은 항상`소수를 '반환이 쿼리처럼 보인다. 당신은 이것을 시도 할 수 있습니다 :

sequenceID = Convert.ToInt64(getIDcmd.ExecuteScalar()); 

나는 당신의 경우에는 어떤 정밀도의 손실이 발생할 것이라고 생각하지 않습니다.

NUMBER의 정밀도를 낮추면 항상 좋은 아이디어가됩니다. Int64NUMBER(19)에 매핑됩니다. 이 방법으로 현재 문제를 해결할 수는 없지만 나중에 더 많은 문제를 예방할 수 있습니다. 예를 들어 Microsoft Oracle 공급자를 사용하여 ID가 ​​포함 된 IDataRecord을 얻는 경우 열이 NUMBER(38)으로 정의되고 NUMBER(19)으로 정의 된 경우 성공할 경우 GetInt64에 대한 호출이 실패합니다 (값이 올바른 범위에있는 경우에도) .