Я пытаюсь вернуть 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 довольно длинный, и код, который я не написал, следует считать работаемым (предполагаемое ключевое слово). Надеюсь, этого достаточно, чтобы понять, что происходит.
Я только что скомпилировал ваш пакет, в 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;
который вы, похоже, можете сделать.
Ошибка: "Неверное количество или типы аргументов при вызове blah" относится к ошибкам в вызывающем коде, а не вызываемом коде.
Вы должны проверить следующее:
Я считаю, что вам нужно передать параметр в вашем .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);