【问题标题】:Returned data type information_schema.identifier does not match expected type返回的数据类型 information_schema.identifier 与预期类型不匹配
【发布时间】:2017-07-15 22:45:40
【问题描述】:

我收到此错误:

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_nameordinal_positiondata_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;

【问题讨论】:

  • 您忘记提供您的 Postgres 版本 (SELECT version();)。

标签: postgresql types plpgsql information-schema


【解决方案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
...

问题 2

我如何将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_identifierDOMAIN 上的varchar。要找出可能的演员表:

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;

列引用在函数创建时转换为基础类型。您会看到通知您这方面的通知。

【讨论】:

    【解决方案2】:

    您最简单(也可能是最安全)的解决方案是将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;
    

    【讨论】:

    • 谢谢,演员作品。但我正在尝试更深入地了解 information_schema 的工作原理
    • 实际上,string 的 data_type 对我来说没有数字那么有用,这就是为什么我想看看 data_type 在 postgres 内部是否表示为整数并获取类型的代码而不是字符串
    • 如果您需要内部表示,不要寻找information_schema,而是寻找pg_catalog 和所有System Catalogs(将数据库信息保存在其internal postgresql-specific方式)
    猜你喜欢
    • 2019-04-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-10-19
    • 2023-03-27
    • 1970-01-01
    • 1970-01-01
    • 2021-08-05
    相关资源
    最近更新 更多