with stored oraclecommand example ejecutar dataaccess c# oracle stored-procedures

stored - oracle store procedure c#



C#Oracle Stored Procedure Parameter Order (3)

Con este

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;

Me parece interesante que si no agrego parámetros en el orden en que fueron definidos, por ejemplo

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;

en lugar de

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;

Los valores devueltos por

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

y

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

intercambiar, aunque ejecutar el procedimiento a través del VS2008 Server Explorer devuelve datos correctos.

¿Por qué es esto?



No soy un buff de Oracle, así que no puedo verificarlo, pero parece que se pasan por posición (en lugar de pasar por su nombre). El equivalente moral a:

EXEC SomeProc ''Foo'', ''Bar''

en lugar de:

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

Esto no es muy poco común: durante años (en los días COM), gran parte de mi código tenía que funcionar con un controlador ADODB de paso por posición.

En este caso, el nombre que proporcione solo sirve como clave local para buscar el valor de la colección de colecciones. Puede verificar fácilmente inventando un nombre:

cmd.Parameters.Add(new OracleParameter("BANANA", ... cmd.Parameters.Add(new OracleParameter("GUITAR", ... ... cmd.Parameters["BANANA"].Value.ToString() cmd.Parameters["GUITAR"].Value.ToString()

Si lo anterior se ejecuta sin error, está pasando por posición. Y se pasan por posición ... luego simplemente agréguenlos en el orden correcto ;-p Y nunca agreguen nuevos parámetros, excepto al final ...


Probablemente pueda establecer el parámetro BindByName en el objeto OracleCommand. Esto funciona para consultas SQL directas con parámetros, no lo he probado con procedimientos almacenados, pero sería lógico ...

cmd.BindByName = true;