sql >> Databasteknik >  >> RDS >> PostgreSQL

Kan jag använda EXCEPTIONS i en FOR LOOP för att tvinga fram fortsättning vid fel?

Ja. Du kan lägga nyttolasten i ett separat kodblock med undantagshantering:

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;

Det finns ett exempel i manualen .

Men jag förstår inte varför du tilldelar tl2 först (istället för tl1 ), vilket är skyldigt att orsaka ett undantag vid den första iterationen av slingan. Du kan undvika problemet a priori genom att använda en FOR loop och istället för en explicit markör i kombination med en utökad fråga. Se nedan.

Även din UPDATE har ingen WHERE skick, vilket nästan säkert är fel.

Och funktionen pgr_trsp() ser minst sagt misstänkt ut. Att skicka kod som text luktar av SQL-injektion. Detta relaterade svar på dba.SE har en bedömning av SQLi i plpgsql:
Postgres-funktioner kontra förberedda frågor

Reviderad funktion i uppdaterad fråga

Att skriva om din kod till att använda uppsättningsbaserad logik istället för looping kan vara renare och snabbare. Till att börja med kan du förenkla till något i stil med detta (fortfarande med en loop, men förenklat):

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;

I synnerhet med hjälp av ...



  1. Räkna instanser i Tabell1 OCH länka till Tabell2

  2. En översikt av pgModeler för PostgreSQL

  3. Få värderäkning från en Oracle-tabell

  4. Hur ser Alter Table-syntaxen ut för att lägga till en DATETIME-kolumn?