PL / SQL выдает возврат скалярного значения последовательности

2

Я пытаюсь вернуть sequence.nextval в мою программу из proc, хранящейся в пакете. Я довольно зелёный, когда дело доходит до PL/SQL, и я немного рад, что происходит. Ошибка, которая на самом деле возвращается,

PLS-00306: неправильное количество или типы аргументов при вызове строки PROCGET_BOOKMARKID 1, оператор столбца 7 игнорируется.

Вот мой код создания пакета...

create or replace
package BOOKMARKS AUTHID DEFINER is
  type t_Bookmark is ref cursor;

  procedure procGet_Bookmarked_Information(bookmarkId in NUMBER, bookmark out t_Bookmark);
  procedure procInsert_Bookmark(bookmarkId in NUMBER, currExtent in VARCHAR2, selectedLayers in VARCHAR2);
  procedure procGet_Bookmark_Id(bookmarkId out NUMBER);

end BOOKMARKS; 

И proc для get_bookmark_id выглядит так (другие procs работают нормально, поэтому я не буду публиковать их)...


  procedure procGet_Bookmark_Id(bookmarkId out NUMBER)
  IS
  BEGIN
    SELECT seq_bookmarks.nextval INTO bookmarkId
      FROM dual;

  END procGet_Bookmark_Id;

Теперь я уверен, что это не моя последовательность. Я могу получить nextval, если я просто запрошу db непосредственно из моего кода, сделав это...


string sql = string.Format(@"select {0}.seq_bookmarks.nextval from dual", ApplicationSchema);

Где схема приложения - это просто db, к которому я подключаюсь в этом случае.

Итак, мне кажется, что проблема полностью в моем PL/SQL, и это будет иметь смысл, потому что я почти не использовал ее. Любые идеи?

ИЗМЕНИТЬ Итак, вот код, который фактически вызывает вызов.


DataOperationResult result = DataAccess.GetBookmarkId();
DataRow currResult = result.DataTableResult.Rows[0];

Где DataAccess - это класс справедливых запросов, а следующий код для этого конкретного запроса.


string sql = string.Format("{0}.bookmarks.procGet_Bookmark_Id", ApplicationSchema);
DataOperation operation = new DataOperation(DataOperationType.ExecuteScalar, ConnectionString, System.Data.CommandType.StoredProcedure, sql);
return operation.PerformOperation();

Схема приложения - это просто база данных, которую мы хотим запросить. ExecuteScalar довольно длинный, и код, который я не написал, следует считать работаемым (предполагаемое ключевое слово). Надеюсь, этого достаточно, чтобы понять, что происходит.

  • 0
    Можем ли мы увидеть код, который вызывает procGet_Bookmark_Id?
  • 0
    Быстрая проверка ... ваша ошибка говорит "PROCGET_BOOKMARKID", тогда как ваш код говорит "procGet_Bookmark_Id" (с дополнительным подчеркиванием). Это просто SOF, удаляющий подчеркивание?
Показать ещё 1 комментарий
Теги:
stored-procedures
plsql

3 ответа

6
Лучший ответ

Я только что скомпилировал ваш пакет, в PL/SQL Developer он отлично работает.

Проблема связана с типами данных в вашем коде C#.

Из того, что я вижу в описании, вы не привязываете никаких параметров. Вы должны привязывать параметры где-то в своем коде, например

OracleParameter bid = new OracleParameter("bookmarkID", OracleDbType.Number);
bid.Direction = ParameterDirection.Output;
command.Parameters.Add(bid);

Если есть много абстракций, с которыми вам нужно иметь дело, вы можете переопределить процедуру как функцию:

FUNCTION procGet_Bookmark_Id RETURN INTEGER
IS
  res INTEGER;
BEGIN
  SELECT seq_bookmarks.nextval
  INTO res
  FROM dual;
  RETURN res;
END procGet_Bookmark_Id;

и вызовите его в запросе SELECT:

SELECT bookmarks.procGet_Bookmark_id FROM dual;

который вы, похоже, можете сделать.

  • 0
    Вы правы, я не связываю никакие параметры, наверное, я не осознавал, что мне нужно связывать выходные параметры в моем коде C #. Извините, что не публиковал команды .net, я просто надеялся, что того, что я написал, будет достаточно, реальные команды C # находятся за тонной абстракции, написанной задолго до меня.
2

Ошибка: "Неверное количество или типы аргументов при вызове blah" относится к ошибкам в вызывающем коде, а не вызываемом коде.

Вы должны проверить следующее:

  • Параметр, который вы передаете, представляет собой NUMBER или тип, который можно легко преобразовать из NUMBER.
  • Параметр, который вы передаете, представляет собой переменную, а не литерал или константу.
  • 0
    Видите, это то, что я запутался. Я не передаю никаких параметров в процесс. Должна ли я быть? Запрос должен просто запрашивать seq.nextval, создает его как процедура procGet_Bookmark_Id (bookmarkId out NUMBER); Требуется номер для передачи?
  • 0
    @Carter: Да. Если вы объявляете параметр OUT, вам нужно передать параметр из вызывающего кода, который получит значение, установленное процедурой.
1

Я считаю, что вам нужно передать параметр в вашем .net-коде. Имя, которое вы указываете параметру, должно быть идентичным в коде .net и определении процедуры.

-OR -

Используйте функцию PL/SQL вместо процедуры. Вам не нужно будет использовать параметр вообще.

Изменить: если вы используете поставщик Microsoft, вам понадобится параметр возврата. Вот код .net.

// proc is the procedure name, oraConn is the oracle connection
OracleCommand cmd = new OracleCommand(proc, oraConn);
cmd.CommandType = System.Data.CommandType.StoredProcedure;

OracleParameter ret = new OracleParameter();
ret.Direction = System.Data.ParameterDirection.ReturnValue;
ret.OracleType = OracleType.Number;
cmd.Parameters.Add(ret);

Ещё вопросы

Сообщество Overcoder
Наверх
Меню