Мы разрабатываем автономное приложение, которое хранит свои данные в базе данных. Мы используем набор данных и адаптеры таблиц для связи с базой данных. Одним из основных требований является возможность использования приложения SQL Server, Oracle и MySQL. Для этого мы сделали запросы к поставщику ТА независимыми. Мы используем ODBC-провайдер.

Он отлично работает для SQL Server и MySQL, но с Oracle у нас были проблемы. Одна из проблем, которую мы не можем преодолеть, - это ошибка преобразования десятичного числа в Int64.

Таблицы Oracle используют ЧИСЛО (38) для системных идентификаторов (полей автоинкремента), которые, как кажется, отображаются в десятичном формате. Однако мы используем Int64 / long в DataSet / TA, поскольку SQL Server и MySQL используют BIGINT. (Обратите внимание, что адаптеры таблиц DataSEt вначале автоматически генерировались из схемы SQL Server.)

Мы получаем исключение приведения при получении значения ЧИСЛО от Oracle, поскольку он возвращает десятичный объект.

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

Обратите внимание, что мы пытались снизить число точности в Oracle (например, NUMBER (10)), как мы видели с другими записями форума, но безуспешно.

Это проблема ODBC? Если мы перейдем к другому провайдеру, решим проблему?

2
Markos Fragkakis 22 Июл 2009 в 12:48

3 ответа

Лучший ответ

Если sequence_id - это имя вашей последовательности, ваш запрос не выглядит правильно в Oracle. Вы бы запросили последний заданный идентификатор с таким запросом, как:

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

Приведение не должно быть проблемой (если в диапазоне int64).

1
Vincent Malgrat 22 Июл 2009 в 12:56

Вы можете запустить это, чтобы узнать, какой тип действительно возвращается, а затем перейти оттуда:

System.Windows.Forms.MessageBox.Show(getIDcmd.ExecuteScalar().GetType().ToString());
1
awe 22 Июл 2009 в 13:10

Кажется, что этот запрос всегда будет возвращать десятичное число. Вы можете попробовать это:

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

Я не думаю, что в вашем случае произойдет потеря точности.

Обратите внимание, что снижение точности вашего ЧИСЛА всегда является хорошей идеей: Int64 сопоставляется с NUMBER(19). Это не решит вашу проблему, но может предотвратить появление новых проблем в будущем. Например, если вы получили IDataRecord включая ваш идентификатор (с использованием поставщика Microsoft Oracle), вызов GetInt64 завершится ошибкой, если ваш столбец определен как NUMBER(38), и завершится успешно, если определен как NUMBER(19) (даже если значение находится в правильном диапазоне).

1
Mac 22 Июл 2009 в 13:20