Boucle à travers les colonnes de l'ENREGISTREMENT
J'ai besoin de faire une boucle par type RECORD
éléments clés/index, comme je peux le faire en utilisant un tableau de structures dans d'autres langages de programmation.
Par exemple:
DECLARE
data1 record;
data2 text;
...
BEGIN
...
FOR data1 IN
SELECT
*
FROM
sometable
LOOP
FOR data2 IN
SELECT
unnest( data1 ) -- THIS IS DOESN'T WORK!
LOOP
RETURN NEXT data1[data2]; -- SMTH LIKE THIS
END LOOP;
END LOOP;
Il y a des solutions .. selon les types de données en cours d'utilisation. Pouvez-vous s'il vous plaît ajouter une table classique de définition et de certaines données, par exemple, la forme souhaitée de la production et de la définition de la fonction, y compris les paramètres? Est la fonction qui est prévu pour le table ou pour les tables différentes? Ce dernier vous demande de remettre un nom de table via le paramètre et l'utilisation du SQL dynamique ...
OriginalL'auteur RKI | 2012-10-25
Vous devez vous connecter pour publier un commentaire.
@Pavel expliqué, il n'est pas simplement possible de parcourir un dossier, comme vous pourriez parcourir un tableau. Mais il y a plusieurs façons de contourner cela, en fonction de vos besoins exacts. En fin de compte, puisque vous voulez pour remettre toutes les valeurs dans la même colonne, vous avez besoin de les jeter à la même type
text
est évident terrain commun, car il est une représentation de texte pour chaque type.Rapide et sale
Dire, vous avez un tableau avec une
integer
, untext
et undate
colonne.Alors la solution peut être aussi simple que:
Fonctionne pour les deux premières lignes, mais ne parvient pas pour les cas particuliers de la ligne 3 et 4.
Vous pouvez facilement résoudre le problème par des virgules dans le texte de la représentation:
Ce serait beau travail - à l'exception de la ligne 4 qui a des guillemets dans le texte de la représentation. Ceux-ci sont échappés par les doubler. Mais le constructeur array aurait besoin d'eux s'est échappé en
\
. Je ne sais pas pourquoi cette incompatibilité est là ...Rendements:
Mais vous devez:
Bonne solution
Si tu savais les noms de colonne à l'avance, une solution propre serait simple:
Depuis de fonctionnement sur les registres de bien connaître le type, vous pouvez simplement interroger le catalogue du système:
Mettre cela dans une fonction avec le SQL dynamique:
Appel:
Retourne:
Cela fonctionne sans installation de modules supplémentaires. Une autre option est d'installer le hstore de l'extension et de l'utiliser comme @Craig montre.
Je pense que vous vous méprenez. Les solutions finales est uniquement pour ce cas. Essayer de lire à nouveau.
Merci! Maintenant j'ai compris. Je vais essayer votre solution dans quelques jours.
OriginalL'auteur Erwin Brandstetter
PL/pgSQL n'est pas vraiment conçu pour ce que vous voulez faire. Elle ne considère pas qu'un enregistrement soit itératif, c'est un n-uplet de peut-être différents et des types de données incompatibles.
PL/pgSQL a
EXECUTE
pour SQL dynamique, maisEXECUTE
requêtes ne peut pas se référer à PL/pgSQL, des variables commeNEW
ou d'autres enregistrements directement.Ce que vous peut faire est de convertir l'enregistrement à un
hstore
clé/valeur de la structure, puis itérer sur leshstore
. Utilisationeach(hstore(the_record))
, qui produit un ensemble de lignes dekey,value
des n-uplets. Toutes les valeurs sont exprimées à leurtext
représentations.Ce jouet de fonction montre une itération sur un enregistrement par la création d'un anonyme
ROW(..)
- qui ont des noms de colonnef1
,f2
,f3
- puis de conversion que pourhstore
, de parcourir sa colonne/paires de valeur, et le retour de chaque paire.En réalité, vous ne jamais l'écrire de cette façon, puisque la totalité de la boucle peut être remplacé par une simple
RETURN QUERY
déclaration et il fait la même choseeach(hstore)
n'a de toute façon - c'est seulement de montrer commenteach(hstore(record))
œuvres, et la fonction ci-dessus ne doit jamais être utilisé.Je suppose que c'est ce Erwin est fait référence à
create or replace function row_to_jsonarray(r anyelement) returns json language sql immutable AS $$ select to_json(array (select value from each(hstore(r)) ) ); $$
; Œuvres dans PostgreSQL 9.4. Mais l'esprit que hstore ne garantit pas l'ordre des colonnes dans l'enregistrement doit être la même dans le json.OriginalL'auteur Craig Ringer
Cette fonctionnalité n'est pas prise en charge dans plpgsql - Enregistrement n'EST PAS hachage tableau comme d'autres langages de script - il est semblable à C ou ADA, où cette fonctionnalité est impossible. Vous pouvez utiliser un autre langage PL comme PLPerl ou PLPython ou quelques astuces que vous pouvez parcourir avec HSTORE type de données (extension) ou via le SQL dynamique
voir Comment définir la valeur de la variable composée champ à l'aide de SQL dynamique
Mais demande à ce que cette fonctionnalité signifie généralement, si vous faites un peu de mal. Lorsque vous utilisez PL/pgSQL vous avez à penser de manière différente que vous utilisez Javascript ou Python
OriginalL'auteur Pavel Stehule
regress=# SELECT unnest(ROW(1,2,'test'));
ERROR: function unnest(record) does not exist
Oui, il aurait à choisir
data1.myArray
. Au moins je suppose que c'est un tableau qu'il est en train d'essayer deunnest
ilJe pense qu'il veut
unnest
un enregistrement dans des paires clé/valeur. Qui n'est tout simplement pas pris en charge et n'a pas de sens dans un typée modèle relationnel, sauf si vous aimez hstore ne et convertir toutes les valeurs de texte, de toute façon.Merci! Mais vous ne comprenez pas ma question.
OriginalL'auteur Clodoaldo Neto
Si vous commandez vos résultats avant le bouclage, allez-vous accomplir ce que vous voulez.
fera exactement ce dont vous avez besoin. C'est aussi le moyen le plus rapide pour effectuer ce genre de tâche.
OriginalL'auteur Loek Bergman