cursor loop in PostgreSQL

柔情痞子 提交于 2019-12-11 02:24:07

问题


This below code is a cursor in PostgreSQL 9.0. I want to fetch my records by joining more than one table and i am getting JSON data from that join.

So I want to loop those records and parse that json using query something like

SELECT "Dump"->'activities-steps'->0->'value' as "steps"
FROM "ActivitySessionDump" where "Id"=42594321345021288   

then i have to get data from this query and insert to some other table like

insert to table name (key,value);

So i prepared one readonly cursor to achieve this task

begin work;

DECLARE 
sessionids INSENSITIVE no scroll CURSOR FOR 
SELECT asn."Id",asn."UserId",asn."ActivityId",ad."Dump"
  FROM "ActivitySession" as asn inner join "ActivitySessionDump" as ad 
  on asn."Id"=ad."ActivitySessionId" 
  where asn."CreatedAt" between now() - interval '5 hours' and now() and asn."ActivityId"=1 
for read only;
---- i want her loop should start and i will parse a json Dump by executing query--------

--------insert record to another table---------------

---end loop-----------
FETCH next FROM sessionids;
CLOSE sessionids;
COMMIT WORK;

Any help really appreciated.Thanks


回答1:


Since you cannot loop in SQL, you'll have to use PL/pgSQL, for example with a DO statement.

In your case, that could look like this:

DO
$$DECLARE
   asn_id ...;
   asn_userid ...;
   ...
   c refcursor;
BEGIN
   /* assign the SQL cursor to the refcursor variable */
   c := 'sessionids';

   LOOP
      FETCH c INTO asn_id, asn_userid, ...;
      IF NOT FOUND THEN EXIT; END IF;

      /* process the result row */

   END LOOP;
END;$$;

Of course it is a bit awkward to declare a cursor in SQL and use it in PL/pgSQL. It might be better to put the statement in a FOR loop like this:

FOR asn_id, asn_userid, ... IN
  SELECT ...
LOOP

   /* process the result row */

END LOOP;

Maybe you could even squeeze the whole thing into a single INSERT statement, that would be most efficient:

INSERT INTO ...
   (SELECT ...);



回答2:


As far as I can tell, the loop or function is unnecessary. It can be replaced with a simple query using string aggregation:

SELECT string_agg("Dump"->'activities-steps'->0->'value', ',') as steps 
FROM "ActivitySessionDump" d
WHERE d."ActivitySessionId" IN (SELECT asn."Id"
                                FROM "ActivitySession" as asn 
                                  join "PersonDataSource" as pd on pd."UserId" = asn."UserId" 
                                where asn."CreatedAt" between now() - interval '5 days' and now() 
                                  and asn."ActivityId" = 1  
                                  and pd."DataSourceId" = 1);

Unrelated, but: you should really avoid those dreaded quoted identifiers




回答3:


here is the code for my question and i am unable to EXECUTE 'SELECT rec."Dump"::json#>''{activities-steps,0}''->>''value'' as steps ' INTO jsonrec; line;

SELECT '{"activities-steps":[{"dateTime":"2016-10-17","value":"4023"}]}'::json#>'{activities-steps,0}'->>'value' as steps; where as i can execute this code in console.

but inside function i cant.

CREATE OR REPLACE FUNCTION ThirdPartyDataParse()
RETURNS text AS $$
DECLARE 
sessionid NO SCROLL CURSOR FOR SELECT asn."Id",asn."UserId",asn."ActivityId",pd."DataSourceId",ad."Dump"::TEXT
   FROM "Development"."ActivitySession" as asn inner join "Development"."PersonDataSource" as pd on pd."UserId" = asn."UserId" inner join "Development"."ActivitySessionDump" as ad 
   on asn."Id"=ad."ActivitySessionId" where asn."CreatedAt" between now() - interval '5 days' and now() and asn."ActivityId"=1  and pd."DataSourceId"=1 for read only;
titles TEXT DEFAULT '';
rec record;
jsonrec record;
 BEGIN
 OPEN sessionid;
loop

FETCH sessionid INTO rec;
--raise notice '%d',rec."UserId";
   if not found then
        exit ;
   end if;
 EXECUTE 'SELECT rec."Dump"::json#>''{activities-steps,0}''->>''value'' as steps ' INTO jsonrec;
titles := titles || ',' || jsonrec."steps";
end loop;
return titles;
END;
$$ LANGUAGE plpgsql;


来源:https://stackoverflow.com/questions/40124490/cursor-loop-in-postgresql

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!