Почему я получаю ORA-01722 (неверный номер)? - PullRequest
8 голосов
/ 05 октября 2010

Я использовал параметризованный запрос для вставки значений в таблицу Oracle, например так:

var q = "insert into MyTable(Field1, Field2...) values(:Field1, :Field2...)";
var cmd = new OracleCommand(q, conn); // conn is a pre-existing connection
cmd.Parameters.Add("Field1", field1Val); 
cmd.Parameters.Add("Field2", field2Val);
// etc...
cmd.ExecuteNonQuery();

Это работало нормально, но вдруг это перестало работать, и я получаю ошибку OracleORA-01722 (неверный номер).Я проверил параметры, и все числа, несомненно, являются действительными числами.Я даже подставил фиктивные значения для любых нулей, и я все еще получаю ошибку.Я пробовал тот же запрос в прямом sql (используя OraDeveloper Studio), и он работает, даже с идентичными параметрами.

Как мне отследить этот?

РЕДАКТИРОВАТЬ: за запрос в комментариях, вот инструкция создания таблицы:

CREATE TABLE ALPHA.VISITFINDINGS (
  ID NUMBER(12),
  VISITID NUMBER(12) NOT NULL,
  DESCRIPTION VARCHAR2(100),
  CUSTOMIMAGE CLOB,
  VISUALFINDINGSSECTIONMAPID NUMBER(12),
  FINDINGSID NUMBER(12),
  CONSTRAINT FK_VISITFINDINGS_AREA FOREIGN KEY (VISUALFINDINGSSECTIONMAPID)
    REFERENCES ALPHA.VISUALFINDINGSSECTIONMAP(VISUALFINDINGSSECTIONMAPID),
  CONSTRAINT FK_VISITFINDINGS_FINDINGS FOREIGN KEY (FINDINGSID)
    REFERENCES ALPHA.FINDINGS(FINDINGSID),
  CONSTRAINT FK_VISITFINDINGS_VISIT FOREIGN KEY (VISITID)
    REFERENCES ALPHA.VISITS(VISITID),
  CONSTRAINT PK_VISITFINDINGS PRIMARY KEY (ID))
TABLESPACE USERS
STORAGE (
  INITIAL 64K
  MAXEXTENTS UNLIMITED
)
LOGGING;

Ответы [ 3 ]

38 голосов
/ 07 октября 2010

Я уже дал ответ, но думаю, что стоит упомянуть здесь именно то, в чем корень моих проблем, на случай, если кто-то еще найдет этот элемент, когда ищет ответ на свою проблему.

проблема в том, что реализация параметризованных запросов в C # для Oracle содержит серьезную и потенциально опасную ошибку - настоящую «яму в открытом доступе»:

Не имеет значения, как вы называете свои параметры;они должны быть добавлены в том порядке, в котором они указаны в запросе.

Подробнее здесь .

5 голосов
/ 05 октября 2010

Когда вы говорите, что проверили параметры, вы имеете в виду коллекцию Parameters в классе SqlCommand?Возможно, вы не согласны с этой запиской на странице SqlParameter :

Будьте осторожны при использовании этой перегрузки конструктора SqlParameter для указания значений целочисленных параметров.Поскольку эта перегрузка принимает значение типа Object, необходимо преобразовать интегральное значение в тип Object, когда значение равно нулю, как показано в следующем примере C #.Копировать

Parameter = new SqlParameter("@pname", Convert.ToInt32(0));

Если вы не выполните это преобразование, компилятор предполагает, что вы пытаетесь вызвать перегрузку конструктора SqlParameter (string, SqlDbType).

Я бы предложилвместо этого вы используете что-то вроде

cmd.Parameters.Add(
   new SqlParameter("Field1", SqlDbType.Int32) { Value = field1Val });

, чтобы явно установить тип.

1 голос
/ 26 августа 2016
command.BindByName = true;

Пожалуйста, посмотрите это объяснение.

...