sql >> データベース >  >> RDS >> PostgreSQL

FOR LOOPでEXCEPTIONSを使用して、エラー時に継続を強制できますか?

    はい。ペイロードは、例外処理を使用して別のコードブロックに入れることができます:

    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の代わりに )、これはループの最初の反復で例外を引き起こすようにバインドされています。 FOR ループ 拡張クエリと組み合わせた明示カーソルの代わりに。以下を参照してください。

    また、UPDATE WHEREはありません 状態、これはほぼ間違いなく間違っています。

    そして、関数pgr_trsp() 控えめに言っても疑わしいようです。 SQLインジェクションのテキストリークとしてコードを渡す。 dba.SEに関するこの関連する回答には、plpgsqlのSQLiの評価があります。
    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. テーブルにトリガーを追加すると、PSQLExceptionとロックの問題が発生します

    2. csvファイルのいくつかの列をテーブルにコピーします

    3. MySQLデータベースでのリンクリストの取得

    4. java.sql.SQLException:列インデックスが範囲外、0 <1