2011-04-15 11 views
6

estoy usando System.Data.OracleClient que no por el nombre de enlace de parámetros y está verificando el CommandText y parámetros están sincronizados:ORA-01008 con todas las variables obligado

public string CommandText { get; set; } 
    public IEnumerable<OracleParameter> Parameters { get; set; } 

    private void VerifyThatAllParametersAreBound() 
    { 
     var variableNames = Regex.Matches(CommandText, ":\\w+") 
      .Cast<Match>().Select(m => m.Value).ToArray(); 
     var parameteterNames = Parameters.Select(p => p.ParameterName).ToArray(); 

     var unboundVariables = variableNames.Except(parameteterNames).ToArray(); 
     if (unboundVariables.Length > 0) 
     { 
      throw new Exception("Variable in CommandText missing parameter: " 
       + string.Join(", ", unboundVariables) + "."); 
     } 

     var unboundParameters = parameteterNames.Except(variableNames).ToArray(); 
     if (unboundParameters.Length > 0) 
     { 
      throw new Exception("Parameter that is not used in CommandText: " 
       + string.Join(", ", unboundParameters) + "."); 
     } 
    } 

Todavía una consulta tiros ORA-01008: not all variables bound. Al insertar manualmente los valores de los parámetros en el texto de comando ofensivo, la consulta se ejecuta, por lo que los valores de CommandText y Parameters deberían estar bien. Estoy usando: como prefijo, tanto para variables como para nombres de parámetros, y funciona para otras consultas.

¿Cómo puedo identificar la causa de esta excepción?

+1

¿tiene el código que hace las consultas? Además, ¿ha probado con los clientes de oráculo (u otros proveedores) .net? Creo que Microsoft ya no proporciona el cliente Oracle. –

+0

Recuerdo vagamente un problema con uno de los clientes de Oracle de que los parámetros tenían que estar enlazados exactamente en el mismo orden en que aparecían en la consulta o no funcionaría, ¿podría ser ese el problema aquí? – Rup

+0

@Nick - El comando era una actualización con ~ 40 parámetros, por lo que para legibilidad e ip-razones los descarté. Intenté con ODT.NET desde Oracle, pero tuve problemas para implementarlo. (Consulte también el comentario a continuación.) – Grastveit

Respuesta

7

El error no especifica DBNull.Value para valores nulos. Así

new OracleParameter(":Foo", item.Foo) 

tuvieron que precolocado con

item.Foo == null 
    ? new OracleParameter(":Foo", DBNull.Value) 
    : new OracleParameter(":Foo", item.Foo) 

Creo que estaba trabajando antes con ODT.NET sin nulos controles, pero no han confirmado. Aparentemente, System.Data.OracleClient está eliminando parámetros con valor nulo.

0

Creo que Microsoft tiene deprecated OracleClient como parte de ADO.NET hace aproximadamente 2 años.

Es posible que desee considerar el uso de componentes de acceso a datos de Oracle (ODAC odp.net). Fácil de acumular (y verificar recuentos) de parámetros usando la clase OracleParameter. Configurar e instalar documentos encontrados here. Ah, también puedes acceder a su soporte de Entity framework (y LINQ) (¿todavía beta, creo?).

Algo para considerar seriamente de todos modos.

+0

Sí, prefiero usar lo que recomiendan Oracle y Microsoft, pero tuve que poner mis intentos [en espera] (http://stackoverflow.com/questions/5581752/program-defensively-against-odac-instantclient). Con códigos de error de cinco dígitos, estoy un poco decepcionado con los mensajes genéricos. ;) – Grastveit

3

Si pasa nula como valor del parámetro, que se obtiene "No todas las variables ligadas" Si pasa DBNull.Value se obtiene error de ejecución en algún lugar del OracleClient. Para pasar NULL, use string.Empty, OracleClient lo convierte a NULL para cualquier tipo de base de datos.

Cuestiones relacionadas