2017-05-19 3 views
2

Je voudrais sélectionner une seule ligne jointe et ensuite la stocker dans une variable PLSQL que je pourrais ensuite utiliser d'une manière saine.Comment interpréter le résultat d'un SELECT ... JOIN ... INTO dans Postgresql?

Mon meilleur pari semblait le type RECORD, mais il ne me mènera nulle part:

DECLARE cur_acct_and_balance RECORD; 
BEGIN 
    -- we start from _acct 
    SELECT INTO cur_acct_and_balance * 
    FROM Accounts acct JOIN Balances bal ON acct.id = bal.account_id 
    WHERE acct.id = _acct.id AND bal.currency = _currency; 

    -- raise the variable, maybe we learn something... 
    raise exception '%', cur_acct_and_balance; 

donc ... J'ai réussi à mettre quelque chose dans la variable cur_acct_and_balance, mais quoi? : D J'ai essayé augmenter la variable résultante comme une exception, pour l'inspecter, mais pas de chance dans l'interprétation des résultats:

ERROR: (5707,5706,,,"{""logid"":""A/1/2/0""}","2017-05-19 21:44:40.672074","2017-05-19 21:44:40.672074",3170,5707,0,191,"2017-05-19 21:44:40.662101","2017-05-19 21:44:40.662101") 

ce qui était très utile pas. Si je tente d'évaluer comme cur_acct_and_balance.acct IS NOT NULL je reçois

ERROR: record "cur_acct_and_balance" has no field "acct" 

Si je tente d'évaluer comme cur_acct_and_balance.acct.id IS NOT NULL je reçois

ERROR: missing FROM-clause entry for table "acct" 

Je ne ai pas trouvé de bonnes ressources googler, donc j'espère de bonnes personnes ici peuvent être d'une certaine aide^_^

MISE À JOUR

Pour l'instant je réécris simplement le foncti sur ne pas utiliser les jointures, mais je suis toujours intéressé de savoir, je devine qu'une variante de jointure devrait être plus performante.

+1

Utiliser 'jsonb 'Tapez au lieu de' record' non typé pour obtenir plus d'abilitie s pour le gérer: 'déclarer cur_acct_and_balance jsonb; ... Sélectionnez to_jsonb (*) dans cur_acct_and_balance de ...; ' – Abelisto

+0

Bon point, je vais jouer avec ça <3 – bbozo

Répondre

1

Votre enregistrement ne fera pas référence aux tables d'origine, mais seulement à ses colonnes. Vous joignez deux tables dans un seul ensemble. Vous devez donc accéder à vos colonnes ainsi:

cur_acct_and_balance.column_name 

Votre instruction IF:

IF cur_acct_and_balance.id IS NOT NULL THEN 
     --If body 
END IF 
+0

Le problème est, il y a deux tables dans la jointure avec la colonne ID, comment le moteur peut-il savoir lequel? nous voulons dire? Nous nous attendons à ce que chaque ligne de résultats soit 1 compte et 1 balance jointes, toutes les deux toujours présentes, ou aucune – bbozo

+0

La définition d'un alias à ces colonnes résoudrait ce problème. –

1

Il existe plusieurs solutions:

create temp table a on commit drop as select 1 as x, 2 as y; 
create temp table b on commit drop as select 'a'::text as x, 'b'::text as y; 
do $$ 
declare 
    r record; 
    j jsonb; 
begin 
    -- Explicyt type conversion 
    select a.*, row(b.*)::b as b into r from a,b; 
    raise info '%, %, %', r, r.y, (r.b).x; -- Note parenthesizes 

    -- Columns aliases 
    select a.x as a_x, a.y as a_y, b.x as b_x, b.y as b_y into r from a,b; 
    raise info '%, %', r, r.b_y; 

    -- JSONB 
    select to_jsonb(t.*) into j from (select a.*, to_jsonb(b.*) as b from a,b) as t; 
    raise info '%, %', j, j->'b'->>'x'; 
end $$; 

Résultat:

 
INFO: (1,2,"(a,b)"), 2, a 
INFO: (1,2,a,b), b 
INFO: {"b": {"x": "a", "y": "b"}, "x": 1, "y": 2}, a