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

テーブルを反復処理し、各行で計算を実行します

    ループ内で行ごとに更新を行うことは、ほとんどの場合悪い考えであり、そうなります 非常に遅く、スケーリングしません。それを回避する方法を本当に見つける必要があります。

    それを言った後:

    関数が実行しているのは、メモリ内の列値の値を変更することだけです。変数の内容を変更するだけです。データを更新する場合は、updateが必要です ステートメント:

    UPDATEを使用する必要があります ループ内:

    CREATE OR REPLACE FUNCTION LoopThroughTable() 
      RETURNS VOID 
    AS
    $$
    DECLARE 
       t_row the_table%rowtype;
    BEGIN
        FOR t_row in SELECT * FROM the_table LOOP
            update the_table
                set resid = 1.0
            where pk_column = t_row.pk_column; --<<< !!! important !!!
        END LOOP;
    END;
    $$ 
    LANGUAGE plpgsql;
    

    持っていることに注意してください whereを追加するには updateの主キーの条件 それ以外の場合は、すべてを更新するステートメント の行 ループの反復。

    少し より効率的な解決策は、カーソルを使用してから、where current ofを使用して更新を行うことです。

    CREATE OR REPLACE FUNCTION LoopThroughTable() 
      RETURNS VOID 
    AS $$
    DECLARE 
       t_curs cursor for 
          select * from the_table;
       t_row the_table%rowtype;
    BEGIN
        FOR t_row in t_curs LOOP
            update the_table
                set resid = 1.0
            where current of t_curs;
        END LOOP;
    END;
    $$ 
    LANGUAGE plpgsql;
    

    いいえ。関数の呼び出しは、呼び出し元のトランザクションのコンテキストで実行されます。したがって、commitする必要があります SELECT LoopThroughTable()を実行した後 SQLクライアントで自動コミットを無効にしている場合。

    言語名は識別子であることに注意してください。その周りに一重引用符を使用しないでください。 rowなどのキーワードの使用も避けてください 変数名として。

    ドルの見積もり (私がしたように)関数本体の記述も簡単になります



    1. Oracleでvarchar2フィールドを短くするにはどうすればよいですか?

    2. 3つの単純なクエリから複雑なクエリを作成する

    3. データベースから取得したdoubleのnull値を確認する方法

    4. PDO、mysql、トランザクション、およびテーブルのロック