【问题标题】:PL/SQL issues returning a sequence scalar value返回序列标量值的 PL/SQL 问题
【发布时间】:2010-10-06 11:47:23
【问题描述】:

我正在尝试从存储在包中的 proc 将 sequence.nextval 返回到我的程序。当谈到 PL/SQL 时,我是相当绿色的,我对正在发生的事情有点茫然。实际返回的错误是

PLS-00306:对 PROCGET_BOOKMARKID 第 1 行、第 7 列语句的调用中的参数数量或类型错误。

这是我的包创建代码...

创建或替换 包 BOOKMARKS AUTHID DEFINER 是 类型 t_Bookmark 是参考光标; 过程 procGet_Bookmarked_Information(bookmarkId in NUMBER, 书签出 t_Bookmark); 过程 procInsert_Bookmark(NUMBER 中的 bookmarkId,VARCHAR2 中的 currExtent,VARCHAR2 中的 selectedLayers); 过程 procGet_Bookmark_Id(bookmarkId out NUMBER); 结束书签;

get_bookmark_id 的 proc 看起来像这样(其他 proc 工作正常,所以我不打算发布它们)...


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

  END procGet_Bookmark_Id;

现在,我确定这不是我的顺序。如果我只是通过这样做直接从我的代码中查询数据库,我可以获得 nextval...


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

在这种情况下,应用程序架构就是我要连接的数据库。

所以,在我看来,问题完全出在我的 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();

Application Schema 就是我们要查询的数据库。 ExecuteScalar 有点啰嗦,我没有编写的代码应该被认为可以工作(假设关键字)。希望这足以让您了解正在发生的事情。

【问题讨论】:

  • 请问我们可以看到调用 procGet_Bookmark_Id 的代码吗?
  • 快速检查...您的错误显示“PROCGET_BOOKMARKID”,而您的代码显示“procGet_Bookmark_Id”(带有额外的下划线)这只是 SOF 剥离下划线吗?
  • 正在编辑。我认为它一定只是去掉了下划线,因为在我的代码中没有一个地方叫做 procget_bookmarkid。

标签: c# oracle stored-procedures plsql


【解决方案1】:

我刚刚编译了你的包,在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;

,你似乎可以做到。

【讨论】:

  • 你是对的,我没有绑定任何参数,我想我没有意识到我需要在我的 C# 代码中绑定输出参数。很抱歉没有发布 .net 命令,我只是希望我发布的内容就足够了,实际的 C# 命令是在我很久之前写的大量抽象的背后。
【解决方案2】:

错误:“调用 blah 时参数的数量或类型错误”是指调用代码中的错误,而不是被调用代码。

您应该检查以下内容:

  • 您传递的参数是 NUMBER 或可以轻松从 NUMBER 转换的类型。
  • 您传递的参数是一个变量,而不是文字或常量。

【讨论】:

  • 看到这是我很困惑的事情。我没有将任何参数传递给proc。我可以做?查询应该只是要求 seq.nextval,创建它就像过程 procGet_Bookmark_Id(bookmarkId out NUMBER);需要传递一个数字吗?
  • @Carter:是的。如果声明 OUT 参数,则需要从调用代码中传递一个参数,该参数将接收过程设置的值。
【解决方案3】:

我相信您需要在 .net 代码中传入参数。您为参数指定的名称在 .net 代码和过程定义中必须相同。

-或-

使用 PL/SQL 函数而不是过程。您根本不需要使用参数。

编辑:假设您使用的是 Microsoft Provider,您将需要一个返回参数。这是.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);

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-05-06
    • 2015-02-21
    • 1970-01-01
    • 2013-02-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多