在postgresql 9.1.3中执行类型转换函数与postgresql 8.2.22中的不同.连接无法正常工作

RSK*_*RSK 4 sql casting jdbc postgresql-9.1

我使用postgresql版本8.2.22,然后我升级到postgresql 9.1.3并且升级成功完成.

但是现在有些演员阵容不像以前一样!

在Postgres 8.2.22

我运行这两个查询,它们都正常工作:

POSTGRES8222=# select TO_NUMBER('12345678',9999999999.99);

to_number
=========   
 12345678
(1 row)

POSTGRES8222=# select a ||'$'|| b from test;
 ?column?
----------
 1$abcdef
 2$ghijkl
 3$3456
(3 rows)
Run Code Online (Sandbox Code Playgroud)

升级到Postgres 9.1.3后

我运行相同的查询,现在他们抛出错误:

select TO_NUMBER('12345678',9999999999.99);

ERROR:  function to_number(unknown, numeric) does not exist
LINE 1: select TO_NUMBER('12345678',9999999999.99);
               ^
HINT:  No function matches the given name and argument types. You might 
need to add explicit type casts.

EXCEPTION
org.postgresql.util.PSQLException: ERROR: function to_number(numeric, numeric) 
does not exist

Hint: No function matches the given name and argument types. You might need 
to add explicit type casts.

Position: 150



select a ||'$'|| b from test;
ERROR:  operator is not unique: numeric || unknown
LINE 1: select a ||'$'|| b from test;
                 ^
HINT:  Could not choose a best candidate operator. You might need to 
add explicit type casts.

********** Error **********
ERROR: operator is not unique: numeric || unknown
SQL state: 42725
Hint: Could not choose a best candidate operator. You might need to  
add explicit type casts.
Character: 10
Run Code Online (Sandbox Code Playgroud)

为什么postgresql中的转换不像以前那样工作?

kgr*_*ttn 7

从PostgreSQL 8.3开始,自动演员阵容较少.这改变了两个原因:

  1. 许多新的高性能类型正在被引入,自动投射阻止了这些类型能够以"一流"类型的方式使用文字.缩小解析器试图猜测数据类型的情况允许用户可以插入的新类型以更自然的方式使用.

  2. 许多错误报告被证明是人们在不认识到它发生时意外地获得了自动投射的"好处",因此很难找到他们的应用程序编码错误.在8.3发布之后,大约有相同数量的人发帖说改变发现了他们自己代码中隐藏的错误,因为有人抱怨他们的代码现在需要在之前没有的代码.

看起来你试图通过添加隐式类型转换来"解决"这个"问题".这是一个雷区; 我不推荐它.你将限制你可以安全使用的功能,你将无法完成其他人没有做过的古怪小错误,没有人能轻易帮助你.最好修复代码,不要假设这么多隐式转换.

有一两件事可以混淆大家的是,在PostgreSQL里,'1.2'不是一个字符串文字.它是一个未知类型的文字:

test=# select pg_typeof('1.2');
 pg_typeof 
-----------
 unknown
(1 row)

只要可能,PostgreSQL就不会解析文字的类型,这对我所描述的所有新数据类型都很有效.作为最后的手段,如果时间到了它必须解决类型并且没有其他线索,它会将其视为类型text.

test=# select pg_typeof(case when true then '1.2' else null end);
 pg_typeof 
-----------
 text
(1 row)

test=# select pg_typeof(case when true then '1.2' else 2.3 end);
 pg_typeof 
-----------
 numeric
(1 row)

问题2,"aftertypecast"失败,因为你添加了所有隐式类型转换,有多个可能的运算符|| 这可能取决于选择哪个它进行类型转换隐,并有它们之间进行选择没有原则的方式.如果您将该行更改为以下内容,它应该再次起作用:

select a || '$'::text || b from test;
Run Code Online (Sandbox Code Playgroud)

我认为不添加那些隐式转换并更改第一个问题代码会更清晰,更安全:

select TO_NUMBER('12345678',9999999999.99);
Run Code Online (Sandbox Code Playgroud)

至:

select TO_NUMBER('12345678', '9999999999.99');
Run Code Online (Sandbox Code Playgroud)

毕竟,第二个参数是格式字符串,而不是数字.如果您想要执行以下操作,则无法省略引用:

test=# select to_number('12,454.8-', '99G999D9S');
 to_number 
-----------
  -12454.8
(1 row)