PostgreSQL
 sql >> база данни >  >> RDS >> PostgreSQL

Мога ли да използвам EXCEPTIONs в FOR LOOP, за да принудя продължение при грешка?

да Можете да поставите полезния товар в отделен кодов блок с обработка на изключения:

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;

Има пример в ръководството .

Но не виждам защо присвоявате tl2 първо (вместо tl1 ), което непременно ще предизвика изключение при първата итерация на цикъла. Можете да избегнете проблема a priori, като използвате FOR цикъл и вместо изричен курсор в комбинация с подобрена заявка. Вижте по-долу.

Също така, вашата UPDATE няма WHERE състояние, което почти сигурно е грешно.

И функцията pgr_trsp() изглежда меко казано подозрително. Предаването на код като текст мирише на SQL инжекция. Този свързан отговор на dba.SE има оценка на SQLi в plpgsql:
Функции на Postgres срещу подготвени заявки

Одитирана функция в актуализиран въпрос

Пренаписването на вашия код, така че да използва логика, базирана на набор, вместо цикъл може да бъде по-чист и по-бърз. За начало можете да опростите до нещо подобно (все още с цикъл, но опростено):

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;

По-специално, използвайки ...



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. PostgreSQL частичен уникален индекс и upsert

  2. Как да конвертирате времето в дата в местната часова зона по време на заявка

  3. Как да използвам LoggingConnection на Psycopg2?

  4. PostgreSQL - създайте нова база данни чрез pgAdmin UI

  5. date_trunc 5 минути интервал в PostgreSQL