Я делаю следующее:
protected int CreateComponent(DbConnection cnctn, string tableName)
{
int newId;
DbCommand selectCmd = _provFactory.CreateCommand();
selectCmd.Connection = cnctn;
selectCmd.CommandText = string.Format(
"SELECT * FROM {0} WHERE ID = (SELECT MAX(ID) FROM {0})", tableName);
DbDataAdapter dataAdapter = _provFactory.CreateDataAdapter();
dataAdapter.SelectCommand = selectCmd;
...
// create Insert/Update/Delete commands with a builder for the data adapter
...
dataAdapter.Fill(_dataSet, tableName);
newId = Convert.ToInt32(_dataSet.Tables[tableName].Rows[0]["id"]) + 1000000;
DataRow newRow = _dataSet.Tables[tableName].NewRow();
newRow.ItemArray = _dataSet.Tables[tableName].Rows[0].ItemArray;
newRow["ID"] = newId;
_dataSet.Tables[tableName].Rows.Add(newRow);
}
Это прекрасно работает для OleDb и System.Data.OracleClient. Однако с провайдером Oracle.DataAccess.Client я получаю:
Oracle.DataAccess.Types.OracleTruncateException (16550)
с усеченным текстом, полученным из:
at System.Data.Common.DbDataAdapter.UpdatedRowStatusErrors
at System.Data.Common.DbDataAdapter.UpdatedRowStatus
at System.Data.Common.DbDataAdapter.Update
at Oracle.DataAccess.Client.OracleDataAdapter.Update
at System.Data.Common.DbDataAdapter.UpdateFromDataTable
at System.Data.Common.DbDataAdapter.Update
Таблицы, которые я получаю, это большие таблицы, в других есть 61 поле. Типы всех полей ограничены:
VARCHAR2(different lenghts)
VARCHAR2(different lenghts) NOT NULL
FLOAT(126) NOT NULL
NUMBER NOT NULL
DATE
Изменить, чтобы предотвратить слишком много комментариев:
-Я не могу изменить тип данных или что-либо еще в базе данных.
-В DataRow эти столбцы FLOAT (126) имеют тип данных System.Decimal (как при использовании других провайдеров)
-В отличие от того, что я говорил ранее: ID не является первичным ключом. Это уникальный индекс. Таблица не имеет первичного ключа (как определение Oracle) Я должен признать, что я думал, что уникальный индекс является первичным ключом, который может показаться нелепым для людей, знакомых с Oracle. В любом случае я делаю только Вставку 1 ряда. Я не пытался собрать команду вставки, которую я сделаю чуть позже. Построители команд должны обрабатывать таблицы без PK (http://msdn.microsoft.com/en-us/library/tf579hcz.aspx: «Команда SelectCommand также должна возвращать хотя бы один первичный ключ или уникальный столбец.»)
-Это также работает с ODP.NET/Oracle.DataAccess.Client, если:
- Я даю всем значениям FLOAT (126) -колонок 0 до последнего метода
строка. Даже если присвоить значение 1 или 2 любому, возникает то же исключение, когда
DbDataAdapter.Update называется.
или
- Я сам создаю DbDataAdapter.Insertommand и там только
вставить (как код выше), когда вызывается DbDataAdapter.Update. Когда я создаю сам, я даю DbParameter.DbType = DbType.Double для FLOAT (126) -колонок. Если я создаю его сам, все нормальные двойные значения принимаются.
app.config:
<startup><supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0"/></startup>
<system.data>
<DbProviderFactories>
<add name="Oracle Data Provider for .NET"
invariant="Oracle.DataAccess.Client"
description="Oracle Data Provider for .NET"
type="Oracle.DataAccess.Client.OracleClientFactory,
Oracle.DataAccess,
Version=2.112.1.0,
Culture=neutral,
PublicKeyToken=89b483f429c47342" />
</DbProviderFactories>
</system.data>
есть идеи, в чем причина и как я заставлю это работать для всех 3 провайдеров?
Спасибо и наилучшими пожеланиями - Матти