Postgres Les tableaux d'entiers en tant que paramètres?
-
05-09-2019 - |
Question
Je comprends que dans Postgres pur, vous pouvez passer un tableau entier en fonction mais que cela est pas pris en charge dans le fournisseur de données .NET Npgsql.
J'ai actuellement un DbCommand dans lequel je charge un appel à un proc stocké, ajoutez un paramètre et Execute scalaire pour revenir un identifiant pour remplir un objet avec.
Il doit maintenant prendre des entiers n comme arguments. Ceux-ci sont utilisés pour créer des enregistrements enfants reliant le dossier nouvellement créé par son identifiant aux arguments entiers.
Idéalement, je préfère ne pas avoir à faire plusieurs appels ExecuteNonQuery sur mon DbCommand pour chacun des nombres entiers, donc je suis sur le point de construire une chaîne de csv comme paramètre qui sera divisé sur le côté de la base de données.
Je vis normalement dans LINQ 2 SQL savourant l'abstraction Db, en travaillant sur ce projet avec l'accès aux données manuel, il est tout simplement obtenir un peu sale, comment les gens vont généralement de passer ces types de paramètres dans postgres?
La solution
Voir: http://www.postgresql.org/docs/9.1/ statique / arrays.html
Si votre pilote non natif ne vous permet pas de passer de tableaux, vous pouvez:
-
passer une représentation de chaîne d'un tableau (que votre procédure stockée peut alors analyser dans un tableau - voir
string_to_array
)CREATE FUNCTION my_method(TEXT) RETURNS VOID AS $$ DECLARE ids INT[]; BEGIN ids = string_to_array($1,','); ... END $$ LANGUAGE plpgsql;
puis
SELECT my_method(:1)
avec: 1 =
'1,2,3,4'
-
compter sur elle-même pour Postgres coulé à partir d'une chaîne de caractères à un tableau
CREATE FUNCTION my_method(INT[]) RETURNS VOID AS $$ ... END $$ LANGUAGE plpgsql;
puis
SELECT my_method('{1,2,3,4}')
-
choisir de ne pas utiliser les variables de liaison et émettre une chaîne de commande explicite avec tous les paramètres énoncés au lieu (assurez-vous de valider ou échapper à tous les paramètres venant de l'extérieur pour éviter les attaques par injection SQL.)
CREATE FUNCTION my_method(INT[]) RETURNS VOID AS $$ ... END $$ LANGUAGE plpgsql;
puis
SELECT my_method(ARRAY [1,2,3,4])
Autres conseils
Je sais que c'est une vieille question, mais il m'a fallu plusieurs heures pour trouver une bonne solution et je pensais que je transmets ce que j'appris
Vous pouvez toujours utiliser une chaîne correctement formatée. L'astuce est la mise en forme. Notez que si votre tableau est un tableau de chaînes, alors vous aurez besoin d'utiliser array.Select (valeur => string.Format ( « \ » {0} \ », value)) ou l'équivalent. J'utilise ce style pour un tableau d'un type énuméré dans PostgreSQL, car il n'y a pas de conversion automatique du tableau. Dans mon cas, mon type a énuméré quelques valeurs comme « valeur1 », « valeur2 », « value3 », et mon énumération C # a des valeurs correspondant. Dans mon cas, la requête SQL finale se termine à la recherche quelque chose comme (E « { « value1 », « valeur2 »} »), et cela fonctionne. command.Parameters.Add("@array_parameter", string.Format("{{{0}}}", string.Join(",", array));