Function PostgreSQL:错误:$name$不是标量变量
有一个函数返回3个参数,其中一个是复合类型:Function PostgreSQL:错误:$name$不是标量变量,function,postgresql,stored-procedures,syntax-error,plpgsql,Function,Postgresql,Stored Procedures,Syntax Error,Plpgsql,有一个函数返回3个参数,其中一个是复合类型: CREATE OR REPLACE FUNCTION f1( p_text text, OUT result_status_id smallint, OUT result_status_msg text, OUT result_my_type my_type ) RETURNS record AS $BODY$ --body here $BODY$ LANGUAGE 'plpgsql' VOLATILE SECURITY DE
CREATE OR REPLACE FUNCTION f1(
p_text text,
OUT result_status_id smallint,
OUT result_status_msg text,
OUT result_my_type my_type
)
RETURNS record AS
$BODY$
--body here
$BODY$
LANGUAGE 'plpgsql' VOLATILE SECURITY DEFINER
COST 100
复合类型my_类型如下所示:
CREATE TYPE my_type AS
(d_real real,
d_int1 integer,
d_int2 integer,
d_int3 integer,
d_int4 integer,
d_int5 integer,
d_int6 integer,
d_int7 integer,
d_int8 integer,
d_int9 integer,
d_int10 integer,
d_bool boolean,
d_date date,
d_text text
);
还有另一个函数f2在其主体中调用函数f1:
CREATE OR REPLACE FUNCTION f2(
p_text text
)
RETURNS record AS
$BODY$
DECLARE
l_status_id smallint;
l_status_msg text;
l_my_type my_type;
BEGIN
--some logic here
--this statement fails
SELECT * FROM f1(p_text) 'x'
INTO l_status_id, l_status_msg, l_my_type;
--logic continues here
END;
$BODY$
LANGUAGE 'plpgsql' VOLATILE SECURITY DEFINER
COST 100;
问题是,在使用函数执行sql时,我收到以下错误:
ERROR: "l_my_type" is not a scalar variable
如何从另一个函数获取复合类型对象?在f2()函数中,您可以在记录变量中进行选择,然后从中提取所需内容,例如:
CREATE OR REPLACE FUNCTION f2(p_text text )
RETURNS record AS
$BODY$
DECLARE
record_var record;
BEGIN
--this statement was failing
SELECT * FROM f1(p_text) INTO record_var;
SELECT l_my_type.result_my_type.d_int1; -- this should work
END;
$BODY$
LANGUAGE 'plpgsql' VOLATILE SECURITY DEFINER
COST 100;
在f2()函数中,您可以在记录变量中进行选择,然后从中提取所需内容,例如:
CREATE OR REPLACE FUNCTION f2(p_text text )
RETURNS record AS
$BODY$
DECLARE
record_var record;
BEGIN
--this statement was failing
SELECT * FROM f1(p_text) INTO record_var;
SELECT l_my_type.result_my_type.d_int1; -- this should work
END;
$BODY$
LANGUAGE 'plpgsql' VOLATILE SECURITY DEFINER
COST 100;
元组中的复合类型是部分受支持的类型之一,您会遇到一些奇怪的问题(特别是像存储这样的东西,但这是另一个时代的故事)。实现这一目标的一种方法是:
CREATE TYPE return_type_for_function AS (
result_status_id smallint,
result_status_msg text,
result_my_type my_type
);
CREATE FUNCTION myfunc(....) RETURNS return_type_for_function ....
我一直都是这样做的。这比使用OUT变量要成熟一点
下面是一个简单的例子:
or_examples=# create table rel_examples.tabletest (id int);
CREATE TABLE
or_examples=# create table comp_table_test (test rel_examples.tabletest);
CREATE TABLE
or_examples=# create function test(int) returns comp_table_test
immutable language sql as $$
select row(row($1))::comp_table_test; $$;
CREATE FUNCTION
or_examples=# select test(1);
test
---------
("(1)")
(1 row)
元组中的复合类型是部分受支持的类型之一,您会遇到一些奇怪的问题(特别是像存储这样的东西,但这是另一个时代的故事)。实现这一目标的一种方法是:
CREATE TYPE return_type_for_function AS (
result_status_id smallint,
result_status_msg text,
result_my_type my_type
);
CREATE FUNCTION myfunc(....) RETURNS return_type_for_function ....
我一直都是这样做的。这比使用OUT变量要成熟一点
下面是一个简单的例子:
or_examples=# create table rel_examples.tabletest (id int);
CREATE TABLE
or_examples=# create table comp_table_test (test rel_examples.tabletest);
CREATE TABLE
or_examples=# create function test(int) returns comp_table_test
immutable language sql as $$
select row(row($1))::comp_table_test; $$;
CREATE FUNCTION
or_examples=# select test(1);
test
---------
("(1)")
(1 row)
然而,@Chris Travers已经提出了一个可接受的解决方案,在我的例子中,很遗憾,不可能引入一种新类型来从f1函数返回数据 但是,可以在函数f2()中调用函数f1(),仍然可以使用以下语法获取数据:
CREATE OR REPLACE FUNCTION f2(
p_text text
)
RETURNS record AS
$BODY$
DECLARE
l_status_id smallint;
l_status_msg text;
l_my_type my_type;
l_record record;
BEGIN
--some logic here
--this statement is okay now
l_record = f1(p_text);
l_status_id = l_record.result_status_id;
l_status_msg = l_record.result_status_msg;
l_my_type = l_record.result_my_type;
--logic continues here
END;
$BODY$
LANGUAGE 'plpgsql' VOLATILE SECURITY DEFINER
COST 100;
然而,@Chris Travers已经提出了一个可接受的解决方案,在我的例子中,很遗憾,不可能引入一种新类型来从f1函数返回数据 但是,可以在函数f2()中调用函数f1(),仍然可以使用以下语法获取数据:
CREATE OR REPLACE FUNCTION f2(
p_text text
)
RETURNS record AS
$BODY$
DECLARE
l_status_id smallint;
l_status_msg text;
l_my_type my_type;
l_record record;
BEGIN
--some logic here
--this statement is okay now
l_record = f1(p_text);
l_status_id = l_record.result_status_id;
l_status_msg = l_record.result_status_msg;
l_my_type = l_record.result_my_type;
--logic continues here
END;
$BODY$
LANGUAGE 'plpgsql' VOLATILE SECURITY DEFINER
COST 100;
你违反了规则 其中,目标可以是记录变量、行变量或 简单变量和记录/行字段的逗号分隔列表 记录或行变量不能是列表中多个项目
的一部分。
解决这个问题的一个办法是:
CREATE OR REPLACE FUNCTION f2(p_text text)
RETURNS record AS
$BODY$
DECLARE
r record;
l_status_id smallint;
l_status_msg text;
l_my_type my_type;
BEGIN
SELECT *
FROM f1(p_text) x -- don't single quote 'x'
INTO r;
l_status_id := r.result_status_id;
l_status_msg := r.result_status_msg;
l_my_type := r.result_my_type;
RETURN r; -- or whatever ..
END;
$BODY$
LANGUAGE plpgsql VOLATILE;
还有更多的方法。这要看你要去哪里。我几乎从不返回匿名记录。你违反了规则
其中,目标可以是记录变量、行变量或
简单变量和记录/行字段的逗号分隔列表
记录或行变量不能是列表中多个项目的一部分。
解决这个问题的一个办法是:
CREATE OR REPLACE FUNCTION f2(p_text text)
RETURNS record AS
$BODY$
DECLARE
r record;
l_status_id smallint;
l_status_msg text;
l_my_type my_type;
BEGIN
SELECT *
FROM f1(p_text) x -- don't single quote 'x'
INTO r;
l_status_id := r.result_status_id;
l_status_msg := r.result_status_msg;
l_my_type := r.result_my_type;
RETURN r; -- or whatever ..
END;
$BODY$
LANGUAGE plpgsql VOLATILE;
还有更多的方法。这要看你要去哪里。我几乎从不返回匿名记录。+1表示可接受的解决方案,但我发现了你在我的答案中可以找到的技巧+1表示可接受的解决方案,但我发现了你在我的回答中可以找到的技巧,也可以,并且在x附近没有单引号。如果没有别名函数,那么重要的部分是解释您遇到的错误(对于您和一般公众)。如前所述,有多种方法可以解决这个问题。我选择了一个不同的例子,在你已经发布了简单的作业之后。这也没关系,它在x附近没有单引号。如果没有别名函数,那么重要的部分是解释您遇到的错误(对于您和一般公众)。如前所述,有多种方法可以解决这个问题。在你自己发布简单作业后,我选择了另一个例子。这是更简单的表格,是的。另一方面:plpgsql中的赋值运算符是:=
。=
运算符没有为此目的进行记录。考虑一下,这是比较简单的形式,是的。另一方面:plpgsql中的赋值运算符是:=
。=
运算符没有为此目的进行记录。考虑一下这个。