在Postgres中,我正在为我编写的函数(存储过程)编写测试脚本。函数返回整数,插入行的id。在测试脚本中,我想将该id选择为变量,并显示所有内容都已正确插入。
该功能如下所示:
CREATE FUNCTION create_factor(p_name VARCHAR(255))
RETURNS integer AS
$$
DECLARE v_insert_id INTEGER;
BEGIN
....
RETURN v_insert_id AS id;
END;
$$ LANGUAGE plpgsql;
psql脚本如下所示:
BEGIN;
\i create_factor.sql
DO $$
declare factorId integer;
select create_factor into factorId from /* have tried selecting * as well */
create_factor(
'my factor'::VARCHAR(255)
);
\x
select * from factors where name='my factor' and id=factorId;
\x
select k.key_name, v.value
from factors f
join factor_type_key_store k on k.factor_type_id = f.factor_type_id
join factor_key_value_store v on v.factor_type_key_store_id=k.id ;
END$$;
ROLLBACK;
我得到的错误如下:
psql:create_factor_test.sql:31:错误:类型名称无效 " create_factor.id from factorId from
明确提到select into
声明。我已经把功能定义和脚本都搞砸了。不确定我错过了什么。
答案 0 :(得分:2)
变量名和列别名在函数外部不可见。可以使用OUT
参数设置名称。对于返回与您的标量值一样的简单函数,默认列名称默认为函数名称。
CREATE FUNCTION create_factor(p_name text)
RETURNS integer AS
$func$
DECLARE
v_insert_id INTEGER;
BEGIN
....
RETURN v_insert_id; -- AS id -- pointless noise
END;
$$ LANGUAGE plpgsql;
如果您想使用DO
statement进行测试(我没有看到这一点,但是在您的领导下):
DO
$do$
DECLARE
factor_id integer := create_factor('my factor');
BEGIN
RAISE NOTICE 'New factor row: %'
, (SELECT f FROM factors f WHERE name = 'my factor' AND id = factor_id);
END
$do$;
我假设你知道DO
语句中的代码默认是PL / pgSQL,而不是纯SQL吗?
您可以在plpgsql代码中声明一个变量,并在同一行上分配它。
但你不能RETURN
来自DO
声明。你需要另一个功能。 Raising a NOTICE
可能适合你的工作?不知道你想看到什么,我返回示例中的整行。
答案 1 :(得分:1)
你需要使用EXECUTE .... INTO来分配你的变量:
请参阅文档here
函数返回1:
CREATE FUNCTION create_factor( p_name VARCHAR(255)
)
RETURNS integer AS $$
DECLARE v_insert_id INTEGER;
BEGIN
v_insert_id:=1;
RETURN v_insert_id AS id;
END;
$$ LANGUAGE plpgsql;
EXECUTE INTO将函数结果赋给变量:
DO $$
declare factorId integer;
BEGIN
EXECUTE 'select * from
create_factor(
''my factor''::VARCHAR(255)
);' INTO factorId; /* have tried selecting * as well */
RAISE NOTICE 'factorID = %', factorId;
EXECUTE 'WITH f AS (select * from factors where name=''my factor'' and id=' || factorId || ')
select k.key_name, v.value from f join factor_type_key_store k on k.factor_type_id = f.factor_type_id join factor_key_value_store v on v.factor_type_key_store_id=k.id;';
END$$;