(免责声明:PostgreSQL新手.)
好吧,据我所知,我的功能与我见过的样本非常相似.有人能否告诉我如何让这个工作?
create or replace function get_user_by_username(
username varchar(250),
online boolean
) returns setof record as $$
declare result record;
begin
if online then
update users
set last_activity = current_timestamp
where user_name = username;
end if;
return query
select
user_id,
user_name,
last_activity,
created,
email,
approved,
last_lockout,
last_login,
last_password_changed,
password_question,
comment
from
users
where
user_name = username
limit 1;
return;
end;
$$ language plpgsql;
Run Code Online (Sandbox Code Playgroud) 我们编写了一个get_timestamp()定义为的函数
CREATE OR REPLACE FUNCTION get_timestamp()
RETURNS integer AS
$$
SELECT (FLOOR(EXTRACT(EPOCH FROM clock_timestamp()) * 10) - 13885344000)::int;
$$
LANGUAGE SQL;
Run Code Online (Sandbox Code Playgroud)
这在INSERT和UPDATE上用于输入或编辑数据库记录中已创建和已修改字段中的值.但是,我们发现连续添加或更新记录时它返回的值相同.
在检查pgAdmin III中的函数时,我们注意到在运行SQL来构建函数时,在LANGUAGE SQL语句之后注入了关键字IMMUTABLE.该文件指出默认是挥发性的(如果一个都没有出现,VOLATILE是默认的假设),所以我不知道为什么IMMUTABLE注射,然而,改变这种稳定解决了重复值的问题.
注意:如接受的答案中所述,IMMUTABLE永远不会被pgAdmin或Postgres添加到函数中,并且必须在开发期间添加.
我猜测正在发生的事情是这个函数正在被评估并且结果被缓存用于优化,因为它被标记为IMMUTABLE指示Postgres引擎在给定相同(空)参数列表的情况下返回值不应该改变.但是,当在触发器中未使用时,直接在INSERT语句中使用时,该函数将返回一个不同的值五次,然后再返回相同的值.这是由于某些优化算法会出现类似"如果在会话中多次使用IMMUTABLE函数5次,请将结果缓存以供将来调用"?
关于如何在Postgres函数中使用这些关键字的任何说明将不胜感激.对于我们来说STABLE是正确的选择,因为我们在触发器中使用了这个函数,或者还有更多要考虑的东西,例如文档说:
(对于希望查询当前命令修改的行的AFTER触发器不合适.)
但我并不清楚原因.
我正在尝试创建一个在多个表上运行SQL查询并从查询中输出结果表的函数.结果表将有多行.我在这方面遇到了很多困难,而且我已经阅读了建议使用的帖子,RETURN NEXT但我也无法让它工作.根据我的理解RECORD可以使用,因为它采用了输入数据的值.到目前为止,这是我的代码:
CREATE OR REPLACE FUNCTION
most_docs()
RETURNS
SETOF RECORD
AS $$
DECLARE
result RECORD;
BEGIN
CREATE VIEW MOSTDOC AS
SELECT P.country, COUNT(P.country) AS cnt
FROM Producer P, Movie M, ProducerMovie PM
WHERE M.title = PM.title
AND M.year = PM.year
AND P.name = PM.name
AND M.genre = 'Documentary'
GROUP BY P.country;
SELECT DISTINCT M.country INTO result
FROM MOSTDOC M
WHERE M.cnt = (SELECT MAX(M.cnt)
FROM MOSTDOC M);
RETURN result;
END;
$$ LANGUAGE plpgsql;
Run Code Online (Sandbox Code Playgroud)
任何帮助将非常感激.谢谢.
---------- Word …
我使用pgtap来测试postgresql存储过程.其results_eq函数获取存储过程的结果,将其与预期结果进行比较,如果两者不相等则报告失败.
这是我正在运行的代码:
PREPARE result_have AS SELECT select_some_data(12345, 'test_string');
PREPARE result_want AS VALUES ('("2010-09-07 06:05:00+00",100.0)');
SELECT results_eq('result_have', 'result_want');
Run Code Online (Sandbox Code Playgroud)
这是失败输出:
not ok 21
# Failed test 21: "this should return a result"
# Columns differ between queries:
# have: ("(""2010-09-07 06:05:00+00"",100.0)")
# want: ("(""2010-09-07 06:05:00+00"",100.0)")
# Looks like you failed 1 test of 21
Run Code Online (Sandbox Code Playgroud)
我可能真的睡不着觉,但想要和我看起来很相似.
有谁知道为什么这被报告为失败?
有关详细信息的更新:这是我如何定义有问题的存储过程:
CREATE OR REPLACE FUNCTION select_some_data
(
IN p_some_pkey integer,
IN p_some_code varchar(16)
)
RETURNS TABLE(timestamp_utc timestamp with time zone, …Run Code Online (Sandbox Code Playgroud) 我在PostgreSQL文档中找不到任何显示如何声明记录或行,同时声明元组结构的内容.如果您没有定义元组结构,则会收到错误"尚未分配的记录的元组结构是不确定的".
这就是我现在正在做的,它工作正常,但必须有一个更好的方法来做到这一点.
CREATE OR REPLACE FUNCTION my_func()
RETURNS TABLE (
"a" integer,
"b" varchar
) AS $$
DECLARE r record;
BEGIN
CREATE TEMP TABLE tmp_t (
"a" integer,
"b" varchar
);
-- Define the tuple structure of r by SELECTing an empty row into it.
-- Is there a more straight-forward way of doing this?
SELECT * INTO r
FROM tmp_t;
-- Now I can assign values to the record.
r.a := at.something FROM "another_table" at
WHERE at.some_id = 1; …Run Code Online (Sandbox Code Playgroud) 0.0如果以下函数没有返回任何内容,我试图返回:
CREATE OR REPLACE FUNCTION get_height(firstn VARCHAR, lastn VARCHAR)
RETURNS FLOAT AS
$$
DECLARE
height FLOAT = 0.0;
BEGIN
SELECT into height AVG(((p.h_feet * 12) + p.h_inches) * 2.54)
FROM player p
WHERE p.firstname = firstn AND p.lastname = lastn;
RETURN height;
END;
$$ LANGUAGE plpgsql;
Run Code Online (Sandbox Code Playgroud)
我试过搜索它,发现它COALESCE不起作用.有没有人有任何想法如何解决这个问题?
表结构:
create table player(
firstname text
,lastname text
,h_feet INT
,h_inches INT
);
Run Code Online (Sandbox Code Playgroud)
示例数据:
insert into player values ('Jimmy','Howard',6,2);
Run Code Online (Sandbox Code Playgroud) 基本上,至少为了概念验证,我想要一个我可以运行的函数:SELECT res('table_name'); 这将给我SELECT*FROM table_name;的结果.我遇到的问题是架构......在我所拥有的函数的声明中:
创建或替换功能res(table_name TEXT)返回设置此THEPISEPEPROBLEM AS
问题是我不知道如何声明我的返回,因为它要我指定一个表或一个模式,在实际运行该函数之前我不会这样做.
有任何想法吗?
postgresql ×7
plpgsql ×4
function ×2
sql ×2
database ×1
null ×1
pgtap ×1
timestamp ×1
unit-testing ×1
volatility ×1