在PostgreSQL中返回查询记录
我正在尝试编写一个PostgreSQL函数,在数据库中插入数据,然后接收一些数据并返回它。 代码如下:在PostgreSQL中返回查询记录,sql,postgresql,types,casting,plpgsql,Sql,Postgresql,Types,Casting,Plpgsql,我正在尝试编写一个PostgreSQL函数,在数据库中插入数据,然后接收一些数据并返回它。 代码如下: CREATE OR REPLACE FUNCTION newTask(projectid api.objects.projectid%TYPE, predecessortaskid api.objects.predecessortaskid%TYPE, creatoruserid api.objects.creatoruserid%TYPE, title api.objects.title%T
CREATE OR REPLACE FUNCTION newTask(projectid api.objects.projectid%TYPE, predecessortaskid api.objects.predecessortaskid%TYPE, creatoruserid api.objects.creatoruserid%TYPE, title api.objects.title%TYPE, description api.objects.description%TYPE, deadline api.objects.deadline%TYPE, creationdate api.objects.creationdate%TYPE, issingletask api.tasks.issingletask%TYPE)
RETURNS SETOF api.v_task AS
$$
DECLARE
v_objectid api.objects.objectid%TYPE;
BEGIN
INSERT INTO api.objects(objectid, projectid, predecessortaskid, creatoruserid, title, description, deadline, creationdate) VALUES (DEFAULT, projectid, predecessortaskid, creatoruserid, title, description, deadline, creationdate)
RETURNING objectid INTO v_objectid;
INSERT INTO api.tasks(objectid, issingletask) VALUES (v_objectid, issingletask);
RETURN QUERY (SELECT * FROM api.v_task WHERE objectid = v_objectid);
END;
$$ LANGUAGE plpgsql;
对象
和任务
都是表,而v_task
是一个视图,它是两者的结合。我返回刚刚插入的数据的原因是有一些触发器在处理它
到目前为止还不错。我使用返回api.v_任务集
作为我的返回类型和返回查询(…)
,因此期望结果看起来像从v_任务中选择
(具有相同数据类型的相同列)。然而,真正发生的是(pgAdmin的输出,与我的node.js应用程序的结果相同)
:
输出不是几列,而是强制为一列,用逗号分隔。由于我已经在使用一种特殊的记录类型,我不能使用
As
关键字来指定输出的字段。调用表函数
要从返回多个列(实际上是复合类型或行类型)的函数中检索单个列,请使用以下命令调用它:
SELECT * FROM func();
这里的替代方案是:纯SQL
如果您使用PostgreSQL 9.1或更高版本,您可能会对该变体感兴趣。我使用一个可写的CTE来链接插件
可能会尝试将最终选择作为另一个模块添加到CTE中,但在本例中不起作用,因为新插入的值在同一CTE中的视图中不可见。因此,我将其作为一个单独的命令保留在SELECT
:
CREATE OR REPLACE FUNCTION new_task (
_projectid api.objects.projectid%TYPE
,_predecessortaskid api.objects.predecessortaskid%TYPE
,_creatoruserid api.objects.creatoruserid%TYPE
,_title api.objects.title%TYPE
,_description api.objects.description%TYPE
,_deadline api.objects.deadline%TYPE
,_creationdate api.objects.creationdate%TYPE
,_issingletask api.tasks.issingletask%TYPE)
RETURNS SETOF api.v_task AS
$func$
DECLARE
_objectid api.objects.objectid%TYPE;
BEGIN
RETURN QUERY
WITH x AS (
INSERT INTO api.objects
( projectid, predecessortaskid, creatoruserid, title
, description, deadline, creationdate)
VALUES (_projectid, _predecessortaskid, _creatoruserid, _title
, _description, _deadline, _creationdate)
RETURNING objectid
)
INSERT INTO api.tasks
(objectid, issingletask)
SELECT x.objectid, _issingletask
FROM x
RETURNING objectid INTO _objectid;
RETURN QUERY
SELECT * FROM api.v_task WHERE objectid = _objectid;
END
$func$ LANGUAGE plpgsql;
SELECT objectid, projectid, title FROM func();
CREATE OR REPLACE FUNCTION new_task (
_projectid api.objects.projectid%TYPE
,_predecessortaskid api.objects.predecessortaskid%TYPE
,_creatoruserid api.objects.creatoruserid%TYPE
,_title api.objects.title%TYPE
,_description api.objects.description%TYPE
,_deadline api.objects.deadline%TYPE
,_creationdate api.objects.creationdate%TYPE
,_issingletask api.tasks.issingletask%TYPE)
RETURNS SETOF api.v_task AS
$func$
DECLARE
_objectid api.objects.objectid%TYPE;
BEGIN
RETURN QUERY
WITH x AS (
INSERT INTO api.objects
( projectid, predecessortaskid, creatoruserid, title
, description, deadline, creationdate)
VALUES (_projectid, _predecessortaskid, _creatoruserid, _title
, _description, _deadline, _creationdate)
RETURNING objectid
)
INSERT INTO api.tasks
(objectid, issingletask)
SELECT x.objectid, _issingletask
FROM x
RETURNING objectid INTO _objectid;
RETURN QUERY
SELECT * FROM api.v_task WHERE objectid = _objectid;
END
$func$ LANGUAGE plpgsql;