English 中文(简体)
Cast生成返回类型字符变化与预期类型字符变化不匹配(8)
原标题:Cast produces Returned type character varying does not match expected type character varying(8)

昨天我们把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),
  ...

我只给出了select的第一列,因为这是错误发生的地方。在今天之前,此函数运行良好,但现在它出现了以下错误:

ERROR: structure of query does not match function result type
Detail: Returned type character varying does not match expected type character varying(8) in column 1. Where: PL/pgSQL function "getwebregistrarpatient_withdeletes" line 3 at RETURN QUERY [SQL State=42804]

nfa.patient_id_number是文本,正在为patient_for_registrar中的列patient_it_number转换,即varchar(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)),

有人有什么建议吗?

最佳回答

你的功能。。

RETURNS SETOF patient_for_registrar

返回的行类型必须与声明的类型完全匹配。您没有透露patient_for_registrar的定义,这可能是表的相关复合类型。我引用手册中关于复合类型声明

Whenever you create a table, a composite type is also automatically created, with the same name as the table, to represent the table s row type.

如果该类型(表)的第一列定义为varchar(8)(带长度修饰符),则如错误消息所示,您必须返回带相同长度修饰符的varchar(8)varchar不行。字符串长度是否只有8个字符无关紧要,数据类型必须匹配。

varcharvarchar(n)char(m)是PostgreSQL的不同数据类型。

旧版本没有强制使用类型修饰符,但在PostgreSQL9.0中,plpgsql对此进行了更改:

PL/pgSQL now requires columns of composite results to match the expected type modifier as well as base type (Pavel Stehule, Tom Lane)

For example, if a column of the result type is declared as NUMERIC(30,2), it is no longer acceptable to return a NUMERIC of some other precision in that column. Previous versions neglected to check the type modifier and would thus allow result rows that didn t actually conform to the declared restrictions.

Two basic ways to fix your problem:

  • 您可以转换返回的值以匹配patient_for_registrar的定义:

    nfa.patient_id_number::varchar(8)
    
  • 或者,您可以更改RETURNS子句。我会使用返回表并声明匹配的复合类型。这是一个示例

    RETURNS TABLE (patient_for_registrar varchar, col2 some_type, ...)
    

顺便说一句:如果可以避免的话,我从不使用varchar,尤其是不使用长度修饰符。它几乎没有提供类型text不能做的任何事情。如果我需要长度限制,我会使用一个列约束,可以在不重写整个表的情况下进行更改。

问题回答

暂无回答




相关问题
what is wrong with this mysql code

$db_user="root"; $db_host="localhost"; $db_password="root"; $db_name = "fayer"; $conn = mysqli_connect($db_host,$db_user,$db_password,$db_name) or die ("couldn t connect to server"); // perform query ...

Users asking for denormalized database

I am in the early stages of developing a database-driven system and the largest part of the system revolves around an inheritance type of relationship. There is a parent entity with about 10 columns ...

Easiest way to deal with sample data in Java web apps?

I m writing a Java web app in my free time to learn more about development. I m using the Stripes framework and eventually intend to use hibernate and MySQL For the moment, whilst creating the pages ...

join across databases with nhibernate

I am trying to join two tables that reside in two different databases. Every time, I try to join I get the following error: An association from the table xxx refers to an unmapped class. If the ...

How can I know if such value exists in database? (ADO.NET)

For example, I have a table, and there is a column named Tags . I want to know if value programming exists in this column. How can I do this in ADO.NET? I did this: OleDbCommand cmd = new ...

Convert date to string upon saving a doctrine record

I m trying to migrate one of my PHP projects to Doctrine. I ve never used it before so there are a few things I don t understand. In my current code, I have a class similar to this: class ...