C# Oracle 存储过程参数顺序

14

使用这个方法

PROCEDURE "ADD_BOOKMARK_GROUP" (
  "NAME" IN VARCHAR2, 
  "BOOKMARK_GROUP_ID" IN NUMBER, 
  "STAFF_ID" IN VARCHAR2,
  "MAX_NO" IN INT,
  "NUMFOUND" OUT INT, 
  "NEW_ID" OUT NUMBER) IS

BEGIN

NEW_ID := -1;

SELECT COUNT(*) INTO NUMFOUND FROM BOOKMARK_GROUP_TABLE WHERE STAFF_ID = STAFF_ID;

IF NUMFOUND < MAX_NO THEN
    INSERT INTO BOOKMARK_GROUP_TABLE (NAME, BOOKMARK_GROUP_ID, STAFF_ID) VALUES(NAME, BOOKMARK_GROUP_ID, STAFF_ID);
    SELECT BGT_SEQUENCE.currval INTO NEW_ID FROM dual;
END IF;
END;

我觉得很有趣,如果我不按照定义的顺序添加参数,例如:

OracleCommand cmd = new OracleCommand("ADD_BOOKMARK_GROUP", conn);
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.Add(new OracleParameter("NAME", name));
...
cmd.Parameters.Add(new OracleParameter("NEW_ID", OracleDbType.Decimal)).Direction = ParameterDirection.Output;
cmd.Parameters.Add(new OracleParameter("NUMFOUND", OracleDbType.Int32)).Direction = ParameterDirection.Output;

而不是

OracleCommand cmd = new OracleCommand("ADD_BOOKMARK_GROUP", conn);
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.Add(new OracleParameter("NAME", name));
...
cmd.Parameters.Add(new OracleParameter("NUMFOUND", OracleDbType.Int32)).Direction = ParameterDirection.Output;
cmd.Parameters.Add(new OracleParameter("NEW_ID", OracleDbType.Decimal)).Direction = ParameterDirection.Output;

返回的值由

cmd.Parameters["NEW_ID"].Value.ToString()

并且

cmd.Parameters["NUMFOUND"].Value.ToString()

虽然通过VS2008 Server Explorer运行该程序可以返回正确的数据,但是交换发生了。

为什么会这样?

3个回答

35

你可以在OracleCommand对象上设置BindByName参数。这对于带有参数的直接SQL查询有效,我尚未尝试过存储过程,但这是合乎逻辑的...

cmd.BindByName = true;

1
我同意@JohnGietzen,这应该是被接受的答案。 - Ergec
3
这救了我免受头发再脱落的烦恼。由于我来自默认执行此操作的 SQL Server 背景,因此在尝试弄清楚为什么带参数的内联查询不起作用时,我感到非常困扰。谢谢! - Caverman

10

我不是Oracle专家,所以无法验证 - 但这听起来像它们是通过位置传递的(而不是通过名称传递)。道德等同于:

EXEC SomeProc 'Foo', 'Bar'

改为:

EXEC SomeProc @arg1='Foo', @arg2='Bar'

这并不是很罕见的情况 - 多年来(在COM时代),我的许多代码都必须使用按位置传递的ADODB驱动程序工作。

在这种情况下,您提供的名称仅用作本地键来从集合中查找值。您可以通过发明一个名称轻松验证:

cmd.Parameters.Add(new    OracleParameter("BANANA", ...
cmd.Parameters.Add(new    OracleParameter("GUITAR", ...
...
cmd.Parameters["BANANA"].Value.ToString()
cmd.Parameters["GUITAR"].Value.ToString()
如果上述代码没有出现错误,那么它是按位置传递参数。如果它们确实是按位置传递的话... 那么只需按正确的顺序添加它们 ;-p 除非在末尾添加新参数,否则永远不要添加新参数...

所以它们是按位置传递的,虽然按名称传递会更有用。 - JC.

1

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接