Cast生成'返回类型字符变化与预期类型字符变化不匹配(8)'

her*_*oat 3 postgresql varchar types plpgsql postgresql-9.1

昨天我们将PostgreSQL数据库升级到版本9.1.3.我们认为我们已经测试并准备好了所有内容,但我们错过了一项功能.它返回一个这样的表类型:

CREATE OR REPLACE FUNCTION myfunc( patient_number varchar
    , tumor_number_param varchar, facility_number varchar)
  RETURNS SETOF patient_for_registrar
  LANGUAGE plpgsql
AS
$body$
BEGIN
    RETURN QUERY            

    SELECT cast(nfa.patient_id_number as varchar),
    ...
Run Code Online (Sandbox Code Playgroud)

我只给出了select的第一列,因为那是错误发生的地方.在今天之前这个函数运行正常,但现在它给出了这个错误:

错误:查询结构与函数结果类型不匹配
详细信息:返回类型字符变化与第1列中的预期类型字符(8)不匹配.其中:PL/pgSQL函数"getwebregistrarpatient_withdeletes"第3行在RETURN QUERY [SQL State = 42804 ]

nfa.patient_id_number是文本,并正在施放的列patient_id_numberpatient_for_registrarvarchar(8).在阅读了一些之后我认为问题是因为从文本转换时没有指定列长度.但问题是我尝试了各种子串组合来解决这个问题,但没有人解决问题:

substring(cast(nfa.patient_id_number as varchar) from 1 for 8),

cast(substring(nfa.patient_id_number from 1 for 8) as varchar),

cast(substring(nfa.patient_id_number from 1 for 8) as varchar(8)),
Run Code Online (Sandbox Code Playgroud)

有没有人有任何指针?

Erw*_*ter 11

你的功能..

RETURNS SETOF patient_for_registrar
Run Code Online (Sandbox Code Playgroud)

返回的行类型必须与声明的类型完全匹配.您没有透露patient_for_registrar表的相关复合类型的定义.我引用了关于复合类型声明的手册:

每当您创建表时,也会自动创建一个复合类型,其名称与表的名称相同,以表示表的行类型.

如果定义了该类型(表)的第一列varchar(8)(使用长度修饰符) - 如错误消息所示,则必须varchar(8)使用相同的长度修饰符返回; varchar不会这样做.对于这个问题,字符串长度是否只有8个字符,数据类型必须匹配是无关紧要的.

varchar,varchar(n)并且varchar(m)是PostgreSQL的不同数据类型.

较旧的版本没有强制使用类型修饰符,但是对于PostgreSQL 9.0,这已经改为plpgsql:

PL/pgSQL现在需要复合结果列来匹配预期的类型修饰符以及基类型(Pavel Stehule,Tom Lane)

例如,如果结果类型的列声明为NUMERIC(30,2),则返回该列中某些其他精度的NUMERIC将不再可接受.以前的版本忽略了检查类型修饰符,因此允许结果行实际上不符合声明的限制.

解决问题的两种基本方法:

顺便说一句:如果我能避免它,我永远不会使用varchar- 特别是不能使用长度修饰符.它几乎不提供任何类型text无法做到的事情.如果我需要长度限制,我使用一个列约束,可以在不重写整个表的情况下进行更改.

  • 这一切都是很好的信息 - 我正在改变到表返回类型,它就像一个魅力.非常感谢你的帮助. (2认同)