sql >> Databáze >  >> RDS >> PostgreSQL

Mohu použít výjimky ve smyčce FOR LOOP k vynucení pokračování při chybě?

Ano. Užitnou část můžete umístit do samostatného bloku kódu se zpracováním výjimek:

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;

V příručce je příklad .

Ale nechápu, proč přiřazujete tl2 první (místo tl1 ), který je povinen způsobit výjimku při první iteraci cyklu. Problému se můžete a priori vyhnout použitím FOR smyčka a místo explicitního kurzoru v kombinaci s rozšířeným dotazem. Viz níže.

Také vaše UPDATE nemá žádné WHERE stavu, což je téměř jistě špatně.

A funkce pgr_trsp() vypadá přinejmenším podezřele. Předávání kódu jako text zavání injekcí SQL. Tato související odpověď na dba.SE má hodnocení SQLi v plpgsql:
Funkce Postgres vs. připravené dotazy

Auditovaná funkce v aktualizované otázce

Přepsání kódu tak, aby místo smyčkování používal logiku založenou na množinách, může být čistší a rychlejší. Pro začátek můžete zjednodušit na něco takového (stále se smyčkou, ale zjednodušeně):

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;

Zejména pomocí ...



  1. Nelze vytvořit instanci chyby poskytovatele OLE DB jako uživatel ověřování systému Windows

  2. MySQL získá všechny jedinečné hodnoty mezi dvěma sloupci

  3. Výjimka mySQL:Nelze se připojit k žádnému ze zadaných hostitelů MySQL. přes C#

  4. Vložit DO MySQL Z jiné tabulky