0

次のpostgres関数があります

CREATE OR REPLACE FUNCTION refresh_materialized_view(name)
  RETURNS integer AS
$BODY$
DECLARE
  _table_name ALIAS FOR $1;
  _entry materialized_views%ROWTYPE;
  _result INT;
BEGIN

  SELECT * INTO _entry FROM materialized_views WHERE table_name = _table_name;

  BEGIN;
    EXECUTE 'CREATE TEMP TABLE new_materialized_view_rows ON COMMIT DROP AS SELECT * FROM ' || _entry.view_name;
    EXECUTE 'TRUNCATE TABLE ' || _table_name;
    EXECUTE 'INSERT INTO ' || _table_name || ' SELECT * FROM new_materialized_view_rows';

    UPDATE materialized_views
    SET    last_refresh = CURRENT_TIMESTAMP
    WHERE  table_name = _table_name;
  COMMIT;

  EXECUTE 'ANALYZE ' || table_name; 
  RETURN 1;
END
$BODY$
LANGUAGE plpgsql VOLATILE SECURITY DEFINER;

ALTER FUNCTION refresh_materialized_view(name) OWNER TO portal;

関数は非トランザクション コンテキストから呼び出されるため、データを更新するステートメントを次のように囲みました。

BEGIN; 

COMMIT;

これらのステートメントがアトミックに実行されるようにします。ただし、上記のスクリプトを実行すると、次のエラーが発生します。

ERROR:  syntax error at or near ";"
LINE 16:   BEGIN;
4

2 に答える 2

1

関数は常に呼び出し元のトランザクションの一部です。関数でトランザクションをコミットすることはできません。したがって、呼び出し元のコードで次のことを行う必要があります。

begin;
select efresh_materialized_view('foobar');
commit;


関数は非トランザクションコンテキストから呼び出されます
それは不可能です。PostgreSQLではトランザクションなしでは作業できません。おそらく、すべてのステートメントを暗黙的にコミットする「自動コミット」モードを参照していますが、それでもトランザクションです。

于 2012-10-08T10:16:00.333 に答える
0

関数内でCOMMITを使用することはできません。この関数はとにかくトランザクションであるため、2番目のBEGINは必要ありません。同じように。これはあなたのバグでもあり、これは失敗するところです。

于 2012-10-08T10:15:23.320 に答える