2016-05-03 5 views
0

Ich kenne den richtigen Weg Wert aus einer Tabelle einzufügen:
insert into city (pop) select pop+2 from city
Ich will nur wissen, wie Cursor in Pl/pgsql funktioniert.

Ich wünsche Cursor in Schleife verwenden einen Wert einzufügen:Einige Fehler über Cursor in Pl/pgsql

create or replace function test() returns void as 
$$ 
declare 
cur cursor for select pop+2 from city order by pop; 
b int; 
row record; 
begin 
for row in cur 
LOOP 
fetch cur into b; 
insert into city(pop) select b; 
end loop; 
end; 
$$ language plpgsql  

Allerdings, wenn ich select test() und die Ergebnistabelle Typ ist:

enter image description here

Es ist sehr seltsam, dass nur zwei Reihen sind eingefügt. Also ich möchte wissen, was zu diesem Ergebnis geführt hat?

aktualisieren meine Frage in 2016.04.05:
ich revidieren die Funktion wie folgt aus:

create or replace function test() returns void as 
$$ 
declare 
cur cursor for select * from city order by pop; 
b record; 
begin 
for b in cur 
LOOP 
insert into city(pop) select b.pop+2; 
RAISE NOTICE ' % IS INSERTED' , b; 
end loop; 
end; 
$$ language plpgsql 

Dann habe ich das richtige Ergebnis erhalten:
enter image description here

Aber ich frage mich immer noch warum in der ersten Funktion nur zwei Zeilen eingefügt werden.

+0

Warum verwenden Sie in erster Linie einen (langsamen und ineffizienten) Cursor? Sie können dies ** viel ** effizienter mit einer einzigen Anweisung tun: 'Einfügen in die Stadt (Pop) Wählen Sie Pop + 2 aus der Stadt;'. –

+1

Nur eine Vermutung: Es gibt zwei Abrufe in der Schleife: erstens, implizit, bei 'for row in cur LOOP' und zweitens explizit bei' fetch cur in b; '. Bei jeder Iteration machen Sie also tatsächlich zwei Fetches. – Abelisto

Antwort

1

Ich endlich herausfinden, warum das Ergebnis falsch ist, genau wie Abelistos Kommentar. Ich habe zwei Fetcher in loop bei jedem Schritt:

  1. bei for row in cur LOOP,
  2. bei fetch cur into b

So die erste Reihe where pop=500 und die dritte Zeile, wo pop =1000 bereits geholt in for loop gewesen sein, und es kann nicht von b abgerufen werden.