9 votes

ORA-01008 avec toutes les variables liées

J'utilise System.Data.OracleClient qui lie les paramètres par leur nom et vérifie que CommandText et Parameters sont synchronisés :

    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) + ".");
        }
    }

Une question se pose encore ORA-01008: not all variables bound . Lorsque l'on insère manuellement les valeurs des paramètres dans le texte de commande incriminé, la requête s'exécute, ce qui signifie que le texte de commande et les valeurs des paramètres doivent être corrects. J'utilise : comme préfixe pour les variables et les noms de paramètres et cela fonctionne pour les autres requêtes.

Comment puis-je déterminer la cause de cette exception ?

9voto

Grastveit Points 4444

L'erreur a été de ne pas spécifier DBNull.Value pour les valeurs nulles. Ainsi, l'erreur

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

a dû être remplacée par

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

Je pense que cela fonctionnait auparavant avec ODT.NET sans contrôles de nullité, mais je ne l'ai pas confirmé. Apparemment System.Data.OracleClient abandonne les paramètres dont la valeur est nulle.

3voto

Yaro Points 673

Si vous réussissez nul comme valeur de paramètre, vous obtenez "Not all variables bound". DBNull.Value vous obtenez une erreur d'exécution quelque part dans le client Oracle. Pour passer NULL, utilisez string.Empty OracleClient le convertit en NULL pour tout type de base de données.

2voto

Donal Points 5232

Si vous avez plus d'un paramètre, vous devez définir BindByName a vrai . Par exemple :

OracleCommand cmd = con.CreateCommand();

cmd.BindByName = true;

cmd.Parameters.Add(new OracleParameter("parameter1", parameter1));
cmd.Parameters.Add(new OracleParameter("parameter2", parameter2));

0voto

tbone Points 7147

Je crois que Microsoft a obsolète OracleClient dans le cadre d'ADO.NET il y a environ 2 ans.

Vous pouvez envisager d'utiliser les composants d'accès aux données d'Oracle (ODAC odp.net). La classe OracleParameter permet d'accumuler facilement des paramètres (et d'en vérifier le nombre). Documentation d'installation et de mise en place trouvée aquí . Oh, vous pouvez également accéder au support de leur Entity framework (et LINQ) (encore en beta je crois ?).

Il s'agit en tout cas d'un élément à prendre sérieusement en considération.

0voto

greatbear302 Points 159

Sur la base des réponses et des commentaires ci-dessus, je me suis assuré de ce qui suit pour résoudre ce problème :

  • sont liés dans le même ordre que celui dans lequel ils apparaissent dans la requête
  • le type de paramètre est spécifié
  • Si la même valeur de paramètre est requise plus d'une fois dans le code SQL, nommez chaque paramètre différemment dans le code SQL (je ne suis pas sûr que cela soit nécessaire).

    OracleParameter[] orclParams = new OracleParameter[] { nouveau OracleParameter{ ParameterNam OracleDbType = OracleDbType.Varchar2, Value = "abc" }, new OracleParameter{ [ ] OracleDbType = OracleDbType.Varchar2, Valeur = "abc" }, new OracleParameter{ Par OracleDbType = OracleDbType.Date, Value = myDate } } ; SomeFunction(sqlQuery, orclParams.ToList()) ;

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X