2009-06-06 236 views
11

有了这个C#Oracle存储过程参数顺序

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服务器资源管理器程序返回正确的数据。

这是为什么?

回答

10

我不是Oracle爱好者,所以我无法验证 - 但它听起来像像他们正在传递的位置(而不是通过名称传递)。道德equivelent到:而不是

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并且永远不会添加新的参数,除了最后...

+0

因此,它们按位置传递,虽然名称会很多更有用。 – 2009-06-06 08:56:46

24

你或许可以设置OracleCommand对象上BindByName参数。这适用于带有参数的直接SQL查询,我没有使用存储过程尝试过,但它是合乎逻辑的...

cmd.BindByName = true; 
+5

这是真正的答案。应该被接受。 – 2009-10-28 19:08:00