选择整数返回函数结果到变量postgres

时间:2014-12-27 01:38:08

标签: postgresql stored-procedures plpgsql

在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声明。我已经把功能定义和脚本都搞砸了。不确定我错过了什么。

2 个答案:

答案 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$$;