我收到此错误:
ERROR: structure of query does not match function result type DETAIL: Returned type information_schema.sql_identifier does not match expected type character varying in column 1. CONTEXT: PL/pgSQL function app.get_custom_task_fields(integer,character varying,integer) line 10 at RETURN QUERY
要解决此问题,我需要知道查询中column_name
,ordinal_position
和data_type
的类型。或者更一般地说,information_schema.columns
中列的数据类型是什么?如何将sql_identifier
转换为'可输出'格式以使其脱离我的函数?
这是我的功能:
CREATE OR REPLACE FUNCTION app.get_custom_task_fields(sess_identity_id int
,session_code_str varchar
,sess_company_id int)
RETURNS TABLE(field_name varchar,ordinal_position integer,field_type varchar)
AS $$
DECLARE
BEGIN
RETURN QUERY
SELECT t.column_name,t.ordinal_position,t.data_type
FROM INFORMATION_SCHEMA.COLUMNS as t
WHERE table_name = 'task_custom' order by t.ordinal_position;
END;
$$ LANGUAGE PLPGSQL;
答案 0 :(得分:1)
您最简单(也可能是最安全)的解决方案是CAST
要返回的类型的列(使用::
运算符或CAST(xx AS type)
函数):
CREATE OR REPLACE FUNCTION get_custom_task_fields(sess_identity_id int,session_code_str varchar,sess_company_id int)
RETURNS TABLE(field_name varchar,ordinal_position integer,field_type varchar)
AS $$
BEGIN
RETURN QUERY
SELECT t.column_name :: varchar
, t.ordinal_position :: integer
, t.data_type :: varchar
FROM INFORMATION_SCHEMA.COLUMNS as t
WHERE table_name = 'task_custom'
ORDER BY t.ordinal_position;
END;
$$ LANGUAGE PLPGSQL;
答案 1 :(得分:1)
information_schema.columns
中的列的数据类型是什么?
您可以在手册中查找:
或者您可以直接询问Postgres(使用目录表pg_attribute
):
SELECT attname, atttypid::regtype
FROM pg_attribute
WHERE attrelid = 'information_schema.columns'::regclass
ORDER BY attnum;
attname | atttypid ---------------+---------------------------------- table_catalog | information_schema.sql_identifier table_schema | information_schema.sql_identifier table_name | information_schema.sql_identifier ...
如何将
sql_identifier
转换为'可输出'格式以使其脱离我的功能?
要了解任何数据类型的具体信息:
SELECT typname, typtype -- 'd' is for 'domain'
, typbasetype::regtype
FROM pg_type
WHERE oid = 'information_schema.sql_identifier'::regtype;
typname | typtype | typbasetype ----------------+---------+----------- sql_identifier | d | character varying
因此数据类型information_schema.sql_identifier
是varchar
上的DOMAIN
。要找出可能的演员阵容:
SELECT casttarget::regtype, castcontext
FROM pg_cast
WHERE castsource = 'character varying'::regtype;
casttarget | castcontext ------------+------------ regclass | i text | i character | i ...
您可以强制转换为所需的输出类型。但是有一个......
您不需要知道任何这些。只需引用列的数据类型。 The manual about CREATE FUNCTION
通过编写
table_name.column_name%TYPE
来引用列的类型。
像这样编写你的函数,你就不会出错:
CREATE OR REPLACE FUNCTION app.get_custom_task_fields(sess_identity_id int
, session_code_str varchar
, sess_company_id int)
RETURNS TABLE(field_name information_schema.columns.column_name%TYPE
, ordinal_position information_schema.columns.ordinal_position%TYPE
, field_type information_schema.columns.data_type%TYPE) AS
$FUNC$
BEGIN
RETURN QUERY
SELECT t.column_name, t.ordinal_position, t.data_type
FROM information_schema.columns t
WHERE t.table_name = 'task_custom'
ORDER BY t.ordinal_position;
END
$FUNC$ LANGUAGE plpgsql;
在函数创建时将列引用转换为基础类型。你会看到告知你的通知。