.NET Oracle SP вызывает ошибки ORA-00604 и ORA-01001 при передаче курсора на основе CTE в приложение - PullRequest
0 голосов
/ 02 февраля 2012

SP выглядит следующим образом: Код SP

код C #, вызывающий его: код C # (это версия после внесения изменений, описанных в обновлении № 3)

Использование System.Data.OracleClient, .NET 3.5 SP1, Oracle Express 11g, Windows 7 x64.

Это прекрасно работает в SQL Developer (2,3). Однако при вызове из .NET это происходит: (см. Обновление 3)

Обновление 1: Использование ExecuteReader с 2 параметрами OUT работает , когда параметр курсора считывает глобальную темп. Стол соединен с обычным столом. Кроме того, это в конечном итоге должно работать внутри ORM (Lightspeed), который может использовать только ExecuteReader.

Обновление 2: Похоже, то же самое происходит в SQL Developer. Я использовал это:

LOOP
  FETCH results INTO v_rec;
  EXIT WHEN results%notfound;
  DBMS_OUTPUT.PUT_LINE(v_rec.name);
END LOOP;

... для извлечения содержимого «результатов»: работает в SP и выдает ORA-01001 при использовании в блоке PL / SQL, вызывающем SP (разумеется, после удаления того же кода внутри SP).

Обновление 3: Превращение «results1» в параметр OUT решило проблему в SQL Developer, которая, очевидно, автоматически закрывала курсор при выходе из области видимости. Однако .NET теперь barfs:

ORA-00604: error occurred at recursive SQL level 1
ORA-01059: parse expected before a bind or execute

См. C # код для параметров. Пробовал методы ExecuteReader, ExecuteNonQuery и ExecuteOracleNonQuery, но безрезультатно.

1 Ответ

1 голос
/ 03 февраля 2012

Я не эксперт по классам System.Data.OracleClient, так как обычно использую Oracle ODP.NET.Поэтому я могу лишь дать вам несколько советов:

Как правило, когда у вас есть хранимая процедура Oracle., Вы вызываете ExecuteNonQuery вместо ExecuteReader, поскольку Oracle никогда напрямую не возвращает набор результатов из хранимой процедуры.Использование ExecuteReader может работать, если у вас есть один OUT параметр типа CURSOR.Но у вас их два.

Что должно сработать в любом случае, это вызвать ExecuteNonQuery и затем извлечь параметры OUT:

int totalNumRows = (int)command.Parameters["total_num_rows"].Value;

using (var reader = (OracleDataReader)cmd.Parameters["results"].Value)
{
    while (reader.Read())
    {
        temp.Add(new Blah { Name = (string)reader["name"] });
    }
}

PS Классы System.Data.OracleClientвычеркнуты.

...