PostgreSQL
 sql >> Base de données >  >> RDS >> PostgreSQL

Npgsql/ Postgresql :la fonction n'existe pas de message d'erreur lorsqu'elle existe

Notez que postgres autorise la la surcharge de fonctions , donc non seulement la fonction NAME doit exister, mais les types des paramètres de la fonction seront également utilisés pour déterminer quelle surcharge utiliser, par exemple

CREATE OR REPLACE FUNCTION public.get_user_by_username(varchar, varchar, boolean)   

N'est pas la même fonction que

CREATE OR REPLACE FUNCTION public.get_user_by_username(varchar, boolean, varchar)

etc

Lors de l'appel de ces fonctions, les noms de paramètres, les types et éventuellement les ordres doivent tous correspondre, sinon vous obtiendrez le

Un piège supplémentaire qui ne cesse de me ronger est les règles de sensibilité à la casse de Postgressql lors de la définition des fonctions. Par exemple, sans aucun "" environnant entre guillemets, la définition de fonction suivante (en utilisant les paramètres par défaut dans pgAdmin 3) :

CREATE FUNCTION MySchema.MyFunction(Parameter1 VARCHAR(40), parameTer2 VARCHAR(20))

enregistre la fonction avec la signature :(utilisez un outil IDE pour le vérifier)

myschema.myfunction(parameter1 VARCHAR(40), parameter2 VARCHAR(20))

Par conséquent, toute tentative en C# de se lier à

command.Parameters.Add("Parameter1", NpgsqlDbType.Varchar, 40);
command.Parameters.Add("parameTer2", NpgsqlDbType.Varchar, 20);

échouera avec l'erreur. Au lieu de cela, vous devrez lier les paramètres en minuscules, c'est-à-dire

command.Parameters.Add("parameter1", NpgsqlDbType.Varchar, 40);
command.Parameters.Add("parameter2", NpgsqlDbType.Varchar, 20);

Sauf si vous définissez la fonction avec des guillemets :

CREATE FUNCTION "MySchema"."MyFunction"("Parameter1" VARCHAR(40), "parameTer2" VARCHAR(20))

C'est pourquoi il est important que vous vous mettiez d'accord sur une convention de casse dans votre base de données/organisation, puis que vous vous y teniez (tout en minuscules est assez courant)

Une alternative, bien qu'également susceptible d'être fragile, est de ne pas du tout se lier avec des paramètres nommés, et d'utiliser à la place la position ordinale du paramètre, pour le lier par exemple

var myParameter = new NpgsqlParameter
{
    // Leave `ParameterName` out entirely,
    Direction = ParameterDirection.Input,
    IsNullable = false,
    NpgsqlDbType = NpgsqlDbType.Varchar,
    Size = 20,
    Value = "SomeValue"
};
command.Parameters.Add(myParameter);
// Same for other parameter(s)