Maison >base de données >tutoriel mysql >Pourquoi les colonnes de ma fonction renvoyant un ensemble sont-elles concaténées lorsqu'elles sont utilisées dans une requête PostgreSQL, et comment puis-je résoudre ce problème ?
Ce problème survient lors de la tentative d'exécution d'une requête à l'aide d'une fonction renvoyant un ensemble dans une autre requête, ce qui entraîne le retour de toutes les fonctions colonnes étant concaténées en une seule colonne.
Le Postgres suivant La fonction, account_servicetier_for_day, prend en compte un identifiant de compte et un jour et renvoie des données historiques :
CREATE OR REPLACE FUNCTION account_servicetier_for_day(_accountid integer, _day timestamp without time zone) RETURNS setof account_dsl_history_info AS $BODY$ DECLARE _accountingrow record; BEGIN Return Query Select * From account_dsl_history_info Where accountid = _accountid And timestamp <= _day + interval '1 day - 1 millisecond' Order By timestamp Desc Limit 1; END; $BODY$ LANGUAGE plpgsql;
Lorsque la fonction est exécutée directement, elle renvoie le résultat attendu avec des colonnes. Cependant, lorsqu'elles sont utilisées dans une requête, les colonnes sont concaténées en une seule :
Select '2014-08-12' As day, 0 As inbytes, 0 As outbytes, acct.username, acct.accountid, acct.userid, account_servicetier_for_day(acct.accountid, '2014-08-12') From account_tab acct Where acct.isdsl = 1 And acct.dslservicetypeid Is Not Null And acct.accountid Not In (Select accountid From dailyaccounting_tab Where Day = '2014-08-12') Order By acct.username
Pour décomposer l'enregistrement renvoyé par la fonction en colonnes individuelles, utilisez la syntaxe SQL :
SELECT * FROM account_servicetier_for_day(20424, '2014-08-12');
Pour Postgres 9.3 et versions ultérieures, la requête peut être réécrite à l'aide de JOIN LATERAL :
SELECT '2014-08-12' AS day, 0 AS inbytes, 0 AS outbytes , a.username, a.accountid, a.userid , f.* -- but avoid duplicate column names! FROM account_tab a , account_servicetier_for_day(a.accountid, '2014-08-12') f -- <-- HERE WHERE a.isdsl = 1 AND a.dslservicetypeid IS NOT NULL AND NOT EXISTS ( SELECT FROM dailyaccounting_tab WHERE day = '2014-08-12' AND accountid = a.accountid ) ORDER BY a.username;
Pour Postgres 9.2 ou version antérieure, utilisez une sous-requête pour appeler la fonction de retour d'ensemble et décomposer l'enregistrement dans la requête externe :
SELECT '2014-08-12' AS day, 0 AS inbytes, 0 AS outbytes , a.username, a.accountid, a.userid , (a.rec).* -- but be wary of duplicate column names! FROM ( SELECT *, account_servicetier_for_day(a.accountid, '2014-08-12') AS rec FROM account_tab a WHERE a.isdsl = 1 AND a.dslservicetypeid Is Not Null AND NOT EXISTS ( SELECT FROM dailyaccounting_tab WHERE day = '2014-08-12' AND accountid = a.accountid ) ) a ORDER BY a.username;
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!