```

    CREATE OR REPLACE FUNCTION testtable()
    RETURNS void AS
    '
    BEGIN
      FOR i IN 2..41 LOOP
        FOR j IN 1..5 LOOP
            IF j = 1  THEN
                INSERT INTO a(test1, test2) VALUES(i,1);
            END IF;
            INSERT INTO b(test3, test4) VALUES(i,j);
        END LOOP;
      END LOOP ;
      COMMIT;
    END;
    '
     LANGUAGE plpgsql ;
    select testtable();
    
```

このエラーが発生してしまいます

```

    cannot begin/end transactions in PL/pgSQL
    
```

原因がわからなくて困っています  
教えてください。
CC BY-SA 4.0
2018-10-12T09:47:36.023
49225
2018-10-13T04:20:22.063
2018-10-12T10:06:40.603
19110
30495
question
sql postgresql
postgreSQL　functionでエラーになってしまう
関数内に`COMMIT`があるのが原因です。  
エラーメッセージの通り、PostgreSQLではユーザ定義関数内でコミットやロールバックといったトランザクション制御はできません。

<https://www.postgresql.jp/document/10/html/plpgsql-structure.html> より:

> PL/pgSQLのBEGIN/ENDは単にまとめるためのもので、トランザクションを始めたり終わらせたりしません。
> 関数とトリガプロシージャは常に外側の問い合わせで確立されたトランザクションの内側で実行されます。
> トランザクションの実行させる文脈はありませんので、これらはトランザクションを開始することもコミットすることもできません。

PostgreSQL 11からは`CREATE PROCEDURE`文でプロシージャを作成し`CALL`で呼ぶときはできるようになるようです。

<https://www.postgresql.org/docs/11/static/plpgsql-transactions.html>
CC BY-SA 4.0
2018-10-13T04:20:22.063
49238
2018-10-13T04:20:22.063
9464
49225
answer