Oracle db дает ORA-01722 для, казалось бы, НИКАКОЙ ПРИЧИНЫ - PullRequest
2 голосов
/ 14 ноября 2011

Я пытаюсь использовать базу данных Oracle с ado.net, и это оказывается болезненным опытом. Я использую Oracle Client (пространства имен Oracle.Data).

Следующий запрос работает нормально из окна запроса:

UPDATE PRINT_ARGUMENT SET VALUE = 'Started' WHERE REQUEST_ID = 1 AND KEYWORD = '{7D066C95-D4D8-441b-AC26-0F4C292A2BE3}'

Когда я создаю OracleCommand, то же самое происходит и с ORA-01722. Я не могу понять, почему.

var cmd = cnx.CreateCommand(); cmd.CommandText = @" UPDATE PRINT_ARGUMENT SET VALUE = :value WHERE REQUEST_ID = :requestID AND KEYWORD = :key";</p> <p>cmd.Parameters.Add(new OracleParameter("requestID", (long)1); cmd.Parameters.Add(new OracleParameter("key", "{7D066C95-D4D8-441b-AC26-0F4C292A2BE3}"); cmd.Parameters.Add(new OracleParameter("value", "Started");</p> <p>cnx.Open(); try { int affected = cnx.ExecuteNonQuery(); } finally { cnx.Close(); }</p> <p>

Когда я проверяю команду в отладчике, параметры отображаются в соответствии с правильными типами: requestID имеет OracleDbType.Int64, ключ и значение - OracleDbType.Varchar2. значения параметров также являются правильными.

Это становится еще более странным, если учесть, что у меня есть другие запросы, которые работают с точно такими же столбцами (requestID, ключевое слово, значение), используя тот же подход - и они работают без сбоев.

Для записи типы столбцов: requestID NUMBER (10,0); ключ VARCHAR2 (30); значение VARCHAR2 (2000).

Согласно Oracle, ORA-01722 «неверный номер» означает, что строку не удалось преобразовать в число. Ни одно из моих строковых значений не является числами, ни один из созданных для них параметров OracleParameters не является числовым, и ни

Ответы [ 2 ]

4 голосов
/ 14 ноября 2011

По умолчанию ODP.NET связывает параметры по позиции , а не по имени, даже если у них есть действительные имена в SQL (а не просто?).Таким образом, вы фактически привязываете requestID к : значение , ключ к : requestID и значение к : key .

Исправьте порядок cmd.Parameters.Add в своем коде или используйте BindByName , чтобы указать ODP.NET использовать имена параметров.

3 голосов
/ 14 ноября 2011

Поскольку вы используете именованные параметры, вы должны сообщить об этом клиенту Oracle. В противном случае ваши параметры перепутаны ( клавиша назначена на : значение ):

OracleParameter parameter = new OracleParameter("requestID", (long)1);
parameter.BindByName = true;
cmd.Parameters.Add(parameter);

Странное и неожиданное поведение, но так оно и есть.

...