sql >> Database >  >> RDS >> PostgreSQL

Kan ik UITZONDERINGEN in een FOR-LUS gebruiken om voortzetting af te dwingen bij een fout?

Ja. U kunt de payload in een apart codeblok plaatsen met uitzonderingsafhandeling:

FOR temp_rec IN tlcursor LOOP
   tl2 := temp_rec; --the location to be updated
   --Do the Routing and UPDATE the taxilocs row.
   BEGIN
      UPDATE taxilocs20120113 
      SET    route = pgr_trsp (
      'SELECT * FROM th_2po_4pgr',
      tl1.map_id, tl1.map_pos, tl2.map_id, tl2.map_pos, false, true);
   EXCEPTION WHEN OTHERS THEN
      -- keep looping
   END;
    tl1 := tl2;
END LOOP;

Er is een voorbeeld in de handleiding .

Maar ik begrijp niet waarom je tl2 . toewijst eerst (in plaats van tl1 ), die ongetwijfeld een uitzondering zal veroorzaken bij de eerste iteratie van de lus. U kunt het probleem a priori vermijden door een FOR lus en in plaats van een expliciete cursor in combinatie met een uitgebreide zoekopdracht. Zie hieronder.

Ook uw UPDATE heeft geen WHERE staat, wat vrijwel zeker verkeerd is.

En de functie pgr_trsp() ziet er op zijn zachtst gezegd verdacht uit. Code doorgeven als tekst ruikt naar SQL-injectie. Dit gerelateerde antwoord op dba.SE heeft een beoordeling van SQLi in plpgsql:
Postgres-functies versus voorbereide query's

Gecontroleerde functie in bijgewerkte vraag

Het herschrijven van uw code om op set gebaseerde logica te gebruiken in plaats van lussen kan schoner en sneller zijn. Om te beginnen kunt u dit vereenvoudigen tot iets als dit (nog steeds met een lus, maar vereenvoudigd):

CREATE OR REPLACE FUNCTION fm_seqrouting()
  RETURNS integer AS
$func$
DECLARE 
   r record;
BEGIN
FOR r IN 
   SELECT oid                                -- no proper pk?
         ,th_2po_4pgr_id                     AS map_id1
         ,th_2po_4pgr_position               AS map_pos1
         ,lead(th_2po_4pgr_id)       OVER w  AS map_id2
         ,lead(th_2po_4pgr_position) OVER w  AS map_pos2
         ,count(*)                   OVER () AS ct
   FROM   testlocs
   WINDOW w AS (ORDER BY veh_id, dt)
   ORDER  BY veh_id, dt              -- you don't need order by columns in result
LOOP
   BEGIN -- may be unnecessary
      UPDATE taxilocs20120113 
      SET    "pgRoute" = pgr_trsp(
                'SELECT * FROM th_2po_4pgr'
               ,r.last_map_id, r.last_map_pos, r.map_id, r.map_pos, false, true)
      WHERE  taxilocs20120113.oid = r.oid;
   EXCEPTION
      WHEN SQLSTATE '55000' THEN NULL;
      WHEN SQLSTATE 'XX000' THEN NULL;
      WHEN SQLSTATE '38001' THEN NULL;
   END;
END LOOP;

RETURN r.ct;

END
$func$  LANGUAGE plpgsql;

In het bijzonder, met behulp van ...



  1. Maak een join-query in loopback.io

  2. Hoe kan ik ON DUPLICATE KEY UPDATE in PDO gebruiken met mysql?

  3. hoe u een MySql-query maakt om het lopende saldo van credit en debet weer te geven wanneer meerdere klanten individuele saldi hebben

  4. Eenvoudigste overgang van MySQL naar MySQLi