Thread: extend INSERT by 'INSERT INTO table FETCH ... FROM cursor' syntax
Please CC me, I am not subscribed. An imaginary SQL statement INSERT INTO table FETCH ... FROM cursor; looks almost the same as currently available INSERT INTO table SELECT ...; I tried it because I needed to insert a row in a table after I DELETEd a set of rows, something like this: BEGIN; DECLARE total CURSOR FOR SELECT SUBSTR(datetime,1,7)||'-01 00:00:00' as month, client, SUM(money) FROM stat WHERE SUBSTR(datetime,1,7)='2003-10' GROUP BY month,client; DELETE FROM stat WHERE SUBSTR(datetime,1,7)='2003-10'; INSERT INTO stat FETCH ALL FROM total; COMMIT; but it does not work, chokes on FETCH ALL. I want to sum up all the money by month, delete all the rows (possibly thousands of them) and insert one row per client with monthly totals. Obviously I cannot swap order of INSERT and DELETE here. I hesitate to post this to pgsql-hackers@postgresql.org, do I have to? ;) -- Alexander Vlasenko
> > Please CC me, I am not subscribed. > > An imaginary SQL statement > INSERT INTO table FETCH ... FROM cursor; > looks almost the same as currently available > INSERT INTO table SELECT ...; > > I tried it because I needed to insert a row in a table > after I DELETEd a set of rows, something like this: > > BEGIN; > DECLARE total CURSOR > FOR SELECT=20 > SUBSTR(datetime,1,7)||'-01 00:00:00' as month, > client, > SUM(money) > FROM stat > WHERE SUBSTR(datetime,1,7)=3D'2003-10' > GROUP BY month,client; > DELETE FROM stat WHERE SUBSTR(datetime,1,7)=3D'2003-10'; > INSERT INTO stat FETCH ALL FROM total; > COMMIT; > > but it does not work, chokes on FETCH ALL. > > I want to sum up all the money by month, delete all the rows > (possibly thousands of them) and insert one row per client > with monthly totals. > > Obviously I cannot swap order of INSERT and DELETE here. > > I hesitate to post this to pgsql-hackers@postgresql.org, > do I have to? ;) > > --=20 > Alexander Vlasenko > Using a temporary table to buffer the result comes to mind. Regards, Christoph
Alexander, > > BEGIN; > > DECLARE total CURSOR > > FOR SELECT=20 > > SUBSTR(datetime,1,7)||'-01 00:00:00' as month, > > client, > > SUM(money) > > FROM stat > > WHERE SUBSTR(datetime,1,7)=3D'2003-10' > > GROUP BY month,client; > > DELETE FROM stat WHERE SUBSTR(datetime,1,7)=3D'2003-10'; > > INSERT INTO stat FETCH ALL FROM total; > > COMMIT; > > > > but it does not work, chokes on FETCH ALL. Well, there's two problems with your program: 1) INSERT INTO .... FETCH ALL is not currently implemented. You would need to use a loop, and insert one row at a time by value. 2) You can't insert the rows you've just deleted from the base tables. In your example, the TOTAL cursor would be empty. I think that what you really want is a temp table. -- -Josh BerkusAglio Database SolutionsSan Francisco
On Monday 27 October 2003 21:35, Josh Berkus wrote: > Alexander, > > > > BEGIN; > > > DECLARE total CURSOR > > > FOR SELECT=20 > > > SUBSTR(datetime,1,7)||'-01 00:00:00' as month, > > > client, > > > SUM(money) > > > FROM stat > > > WHERE SUBSTR(datetime,1,7)=3D'2003-10' > > > GROUP BY month,client; > > > DELETE FROM stat WHERE SUBSTR(datetime,1,7)=3D'2003-10'; > > > INSERT INTO stat FETCH ALL FROM total; > > > COMMIT; [ BTW: quoted-printable is evil ;) ] > > > > > > but it does not work, chokes on FETCH ALL. > > Well, there's two problems with your program: > > 1) INSERT INTO .... FETCH ALL is not currently implemented. You would need > to use a loop, and insert one row at a time by value. Exactly. I was saying that if implemented it may be useful. My example is certainly doable without it but it quickly gets ugly since I can't use this nifty trick. > 2) You can't insert the rows you've just deleted from the base tables. In > your example, the TOTAL cursor would be empty. I think that what you > really want is a temp table. Why do you think it would be empty? It is not. I tried this: BEGIN; DECLARE total CURSORFOR SELECT SUBSTR(datetime,1,7)||'-01 00:00:00' as month, client, SUM(money)FROM statWHERE SUBSTR(datetime,1,7)='2003-10'GROUPBY month,client; DELETE FROM stat WHERE SUBSTR(datetime,1,7)='2003-10'; FETCH ALL FROM total; <=================================== COMMIT; and it does work as expected. FETCH spews out already deleted rows. There is no problem with it. -- Alexander Vlasenko