【问题标题】:How to turn sql into a transaction with multiple statements?如何将sql变成一个多语句的事务?
【发布时间】:2013-09-16 07:38:55
【问题描述】:

我有这个使用 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(...))

【问题讨论】:

  • 您是否尝试过将 PDO 与模拟准备一起使用?
  • 从 PHP 中将每个 SQL 语句作为其自己的语句运行。
  • 我没有使用 PDO。我需要一笔交易,不能做不同的陈述。

标签: php sql postgresql transactions prepared-statement


【解决方案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

来自manual

PostgreSQL 实际上将每个 SQL 语句视为在事务中执行。如果您不发出 BEGIN 命令,则每个单独的语句都有一个隐式的 BEGIN 和(如果成功)COMMIT 包裹它。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-01-07
    • 2023-02-13
    • 2012-04-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多