PostgreSQL
 sql >> Teknologi Basis Data >  >> RDS >> PostgreSQL

Bisakah saya menggunakan PENGECUALIAN dalam FOR LOOP untuk memaksa kelanjutan pada kesalahan?

Ya. Anda dapat menempatkan muatan di blok kode terpisah dengan penanganan pengecualian:

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;

Ada contoh di manual .

Tapi saya gagal melihat mengapa Anda menetapkan tl2 pertama (bukan tl1 ), yang pasti akan menyebabkan pengecualian pada iterasi pertama dari loop. Anda dapat menghindari masalah apriori dengan menggunakan FOR lingkaran dan alih-alih kursor eksplisit dalam kombinasi dengan kueri yang disempurnakan. Lihat di bawah.

Juga, UPDATE . Anda tidak memiliki WHERE kondisi, yang hampir pasti salah.

Dan fungsi pgr_trsp() terlihat mencurigakan untuk sedikitnya. Melewati kode sebagai teks berbau injeksi SQL. Jawaban terkait di dba.SE ini memiliki penilaian SQLi di plpgsql:
Fungsi postgres vs kueri yang disiapkan

Fungsi yang diaudit dalam pertanyaan yang diperbarui

Menulis ulang kode Anda untuk menggunakan logika set-based daripada looping mungkin lebih bersih dan lebih cepat. Sebagai permulaan, Anda dapat menyederhanakan menjadi sesuatu seperti ini (masih dengan loop, tetapi disederhanakan):

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;

Secara khusus, menggunakan ...



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Paksa Postgres untuk menginstal dengan penyandian UTF8, bukan LATIN1?

  2. Postgres:Cara terbaik untuk memindahkan data dari skema publik satu DB ke skema baru DB lain

  3. Bagaimana wadah OpenShift dapat mempelajari ID gambarnya?

  4. Tetapkan id yang sama ke baris dengan kombinasi data yang sama

  5. Sisipan Psycopg2 tidak disimpan