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
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);