2

私はpg_query_paramsを使用してphpで実行するこのSQLを持っています。しかし、BEGIN でトランザクションに変換しようとすると、およびコミット; 次のエラーが表示されます。Query failed: ERROR: cannot insert multiple commands into a prepared statement

同じクエリで複数のステートメントを使用してトランザクションを準備することは可能ですか? または、トランザクションを行うにはどのように変更すればよいですか?

ありがとう!

WITH usr1 AS (
         SELECT id FROM users WHERE mongoid = $1
     ),
     usr2 AS (
         INSERT INTO users (mongoid, shopid, idinshop, attributes)
           SELECT $1, $2, $3, $4
           WHERE  NOT EXISTS (SELECT 1 FROM usr1)
           RETURNING id
     ),
     ses1 AS (
         UPDATE sessions 
           SET traffic=$7, counts=$8 
           WHERE mongoid=$5 
           RETURNING id
     ),
     ses2 AS (
         INSERT INTO sessions (mongoid, shopid, userid, session, traffic, counts)
           SELECT $5, $2, (SELECT id FROM usr1 NATURAL FULL OUTER JOIN usr2),
                  $6, $7, $8
             WHERE  NOT EXISTS (SELECT 1 FROM ses1)
         RETURNING id
     )

INSERT INTO events (shopid, sessionid, userid, type, attributes, mongoid) 
  VALUES (
      $2,
      (SELECT id FROM usr1 NATURAL FULL OUTER JOIN usr2),
      (SELECT id FROM ses1 NATURAL FULL OUTER JOIN ses2),
      $9, $10, $11
);

そして、私は実行します:pg_query_params($db, $sql, array(...))

4

1 に答える 1

1

begin/commitブロックは必要ありません。そのステートメント全体はそれ自体がトランザクションです

create table t (id int primary key);

with s as (
    insert into t values (1) 
    returning id
)
insert into t (id)
select id from s
;
ERROR:  duplicate key value violates unique constraint "t_pkey"
DETAIL:  Key (id)=(1) already exists.

CTE ( with...) 挿入がロールバックされました:

select * from t;
 id 
----
(0 rows)

http://sqlfiddle.com/#!12/0eeef/2

マニュアルから:

PostgreSQL は、実際にはすべての SQL ステートメントをトランザクション内で実行されるものとして扱います。BEGIN コマンドを発行しない場合、個々のステートメントには暗黙的な BEGIN があり、(成功した場合) COMMIT がラップされます。

于 2013-09-16T11:55:19.363 に答える