Sql 如何在Postgres事务内的下一次查询中使用查询结果?

Sql 如何在Postgres事务内的下一次查询中使用查询结果?,sql,postgresql,transactions,plpgsql,common-table-expression,Sql,Postgresql,Transactions,Plpgsql,Common Table Expression,只有当外部引用(用户、会话)已经存在时,我才有一个在数据库中插入事件的查询 若用户不存在,那个么它将被插入,并且应该保存id 如果会话不存在,则使用用户以前的id插入会话 使用先前创建的用户id和会话id插入事件 。我得到这个错误: “PHP警告:pg_query_params():查询失败:错误:语法错误 处于或接近“如果” 对于此查询: BEGIN; SELECT id FROM users WHERE mongoid = $1 (userid); IF not found THEN

只有当外部引用(用户、会话)已经存在时,我才有一个在数据库中插入事件的查询

  • 若用户不存在,那个么它将被插入,并且应该保存id
  • 如果会话不存在,则使用用户以前的id插入会话
  • 使用先前创建的用户id和会话id插入事件
  • 。我得到这个错误:

    “PHP警告:pg_query_params():查询失败:错误:语法错误 处于或接近“如果”

    对于此查询:

    BEGIN;
    SELECT id FROM users WHERE mongoid = $1 (userid); 
    IF not found THEN
        -- inserts user and should remember userid
        INSERT INTO users (mongoid, shopid, idinshop, attributes)
            VALUES ($1, $2, $3, $4) RETURNING id (userid);
    END IF;
    --looks for session and should remember sessionid
    SELECT id FROM sessions WHERE mongoid = $5 (sessionid);
    IF not found THEN
         -- inserts session
         INSERT INTO sessions (mongoid, shopid, userid, session, traffic, counts)
                   VALUES ($5, $2, (userid), $6, $7, $8) RETURNING id (sessionid);
    END IF;
    -- finally inserts the event
    INSERT INTO events (shopid, sessionid, userid, type, attributes, mongoid) 
         VALUES ($2, (sessionid), (userid), $9, $10, $11);
    COMMIT;
    
    稍后编辑:
    我使用下面的答案解决了这个问题!

    您可以使用纯SQL在单个SQL语句中重写您的过程逻辑

    需要博士后9.1或更高版本。
    未测试。如果您想要测试答案,请在问题中提供测试用例

    应该比单个命令快得多()

    请注意并发负载过大时可能出现的并发问题。所提供的单个语句已经不太可能引起问题。但可能性是存在的。 可能的解决方案包括(昂贵)或(也可能昂贵)

    与更多信息相关的答案:

    顺便说一句,第二个
    INSERT
    中缺少关键字
    VALUES
    。谢谢,似乎非常接近。我确实收到了以下错误:PHP警告:pg\u query\u params():查询失败:错误:INSERT的目标列多于表达式第4行:INSERT-INTO-users(mongoid、shopid、idinshop、attri…^提示:插入源是一个行表达式,包含的列数与插入所需的列数相同。您是否意外使用了额外的括号?我将括号从插入中删除到了…选择,它就起作用了。谢谢!您为我节省了4个小时!@Alexandurada:R是的,修正了。在从
    切换到
    选择
    后,我忘了删除参数。还要注意我添加的关于并发性的章节。
    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 (SELECT id FROM sessions WHERE mongoid = $5)
       , 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);