2010-02-04 20 views
5

He verificado que mi método/procedimiento de Oracle funciona correctamente, pero en mi C# siempre obtengo -1 devuelto por ExecuteNonQuery(). En consecuencia, el bool siguiente es siempre falso. Solo utilizamos Triggers en nuestro DB (Oracle) para las instrucciones INSERT. ¿Necesito un disparador para una declaración de actualización?ExecuteNonQuery() devuelve -1 en Actualizar cuando se actualizan los registros

¿Alguna sugerencia de por qué sucedería eso? Su definitivamente la actualización de un registro:

public bool ChangePassword(long UserId, string NewPassword) 
    { 
     int rcds = 0; 
     using (OracleConnection dbConn = new OracleConnection(dbConnString)) 
     using (OracleCommand dbCmd = new OracleCommand("PKG_USER.CHANGE_PASSWORD", dbConn)) 
     { 
      try 
      { 
       string salt = GenerateSalt(); 
       dbCmd.CommandType = CommandType.StoredProcedure; 
       dbCmd.Parameters.Add("p_USER_ID", OracleDbType.Int64, UserId, ParameterDirection.Input); 
       dbCmd.Parameters.Add("P_PASSWORD", OracleDbType.Varchar2, 128, EncodePassword(NewPassword, this.IsPasswordHashed, salt), ParameterDirection.Input); 
       dbCmd.Parameters.Add("P_PASSWORD_SALT", OracleDbType.Varchar2, 128, salt, ParameterDirection.Input); 

       if (dbConn.State != ConnectionState.Open) dbConn.Open(); 
       rcds = dbCmd.ExecuteNonQuery(); 
      } 
      catch (Exception e) 
      { 
       LastError = e.Message + " " + e.Source; 
       rcds = 0; 
      } 
      finally 
      { 
       dbCmd.Dispose(); 
       dbConn.Dispose(); 
      } 
     } 
     return (rcds > 0); 
    } 

Lo sentimos ... aquí está el SP:

PROCEDURE Change_Password(p_User_Id  IN Users.User_Id%TYPE, 
         p_Password  IN Users.Password%TYPE, 
         p_Password_Salt IN Users.Password_Salt%TYPE) IS 


BEGIN 
UPDATE Users 
    SET Password    = p_Password, 
     Password_Salt  = p_Password_Salt, 
     Password_Change_Date = SYSDATE 
WHERE User_Id = p_User_Id; 

FIN change_password;

+0

¿Cómo es tu proceso almacenado? – MikeWyatt

Respuesta

13

Intente devolver explícitamente SQL% ROWCOUNT.

Según MSDN, DbCommand..ExecuteNonQuery siempre devolverá -1 para llamadas a procedimientos almacenados:

Para actualizar, insertar y DELETE, el valor de retorno es el número de filas afectadas por el comando . Para todos los demás tipos de declaraciones, el valor de retorno es -1.

Si recuerdo correctamente de mis días de usar muchos procesos almacenados, creo que necesitaría usar un argumento de salida para devolver cosas como el número de filas actualizadas.

+0

¿Pero no debería el método ExecuteNonQuery devolver el valor, en lugar de un parámetro de salida adicional? Eso es lo que suena en MSDN. – Barryman9000

+0

@ Barryman9000: así no es como lo leo, y tampoco funciona en el SqlCommand; no está emitiendo un comando UPDATE/INSERT/DELETE; está emitiendo una llamada a un proceso almacenado; por lo tanto, el valor de retorno de ExecuteNonQuery va a ser -1. Si desea un valor distinto a ese, deberá devolverlo en un parámetro de salida. (Tenga en cuenta que OracleCommand también puede devolver 0 para una solicitud Create/DropTable: http://msdn.microsoft.com/en-us/library/system.data.oracleclient.oraclecommand.executenonquery.aspx) –

+0

Ah-ha .. . Estaba pensando que desde que estaba actualizando mi tabla, estaba emitiendo y el comando ACTUALIZAR. Tu explicación tiene sentido, gracias. – Barryman9000

1

No soy un chico de Oracle, pero al parecer hay un comando:

set feedback off 

que le impide devolver el recuento de registros afectados. ¿Esta línea está en el procedimiento almacenado? ¿O has intentado 'establecer comentarios sobre'? Funcionalmente, creo que esto es exactamente lo contrario del comando SET NOCOUNT ON/OFF de SQL Server.

Cuestiones relacionadas