如何重用下面函数中调用的pair
返回的值?
CREATE FUNCTION messages_add(bigint, bigint, text) RETURNS void AS $$
INSERT INTO chats SELECT pair($1, $2), $1, $2
WHERE NOT EXISTS (SELECT 1 FROM chats WHERE id = pair($1, $2));
INSERT INTO messages VALUES (pair($1, $2), $1, $3);
$$ LANGUAGE SQL;
我知道SQL query language doesn't support storing simple values in variables和典型的编程语言一样。所以,我查看了WITH
Queries (Common Table Expressions),但我不确定是否应该使用WITH
,无论如何,我无法找出正确的语法。做的事情。
这是我的SQLFiddle以及关于storing chats & messages in PostgreSQL的原始问题。然后插入此函数inserts-if-not-exists。我没有使用交易,因为我想保持快速,并且存储没有消息的聊天并不是那么糟糕,反之则更糟糕。因此,查询顺序很重要。如果有更好的办法,请提供建议。
我想重用该值主要是为了加速代码。但是,SQL解释器是否会自动优化上面的功能?不过,我想写好DRY代码。
答案 0 :(得分:2)
由于函数体是程序性的,因此使用plpgsql
语言而不是SQL:
CREATE FUNCTION messages_add(bigint, bigint, text) RETURNS void AS $$
BEGIN
INSERT INTO chats
SELECT pair($1, $2), $1, $2
WHERE NOT EXISTS (SELECT 1 FROM chats WHERE id = pair($1, $2));
INSERT INTO messages VALUES (pair($1, $2), $1, $3);
END
$$ LANGUAGE plpgsql;
此外,如果要重用的结果是pair($1,$2)
,您可以将其存储到变量中:
CREATE FUNCTION messages_add(bigint, bigint, text) RETURNS void AS $$
DECLARE
pair bigint := pair($1, $2);
BEGIN
INSERT INTO chats
SELECT pair, $1, $2
WHERE NOT EXISTS (SELECT 1 FROM chats WHERE id = pair);
INSERT INTO messages VALUES (pair, $1, $3);
END
$$ LANGUAGE plpgsql;
答案 1 :(得分:1)
create function messages_add(bigint, bigint, text) returns void as $$
with p as (
select pair($1, $2) as p
), i as (
insert into chats
select (select p from p), $1, $2
where not exists (
select 1
from chats
where id = (select p from p)
)
)
insert into messages
select (select p from p), $1, $3
where exists (
select 1
from chats
where id = (select p from p)
)
;
$$ language sql;
只有在聊天中存在时才会插入消息。
答案 2 :(得分:0)
我实际上对这部分问题没有答案,但无论如何我都会解决这个问题,因为Markdown SUCKS and Stack Overflow doesn't support the start
attribute on the ol
element。
行。现在,我们在2,:-) PostgreSQL functions are transactional。因此,订单实际上并不重要,因为两个插入都将在一个事务中一起提交。
不,优化器仅在使用常量(非变量)参数调用不可变函数时预先计算它们,例如pair(4, 5)
。请参阅Function Volatility Categories。