3

我正在尝试解决遗留数据库的问题。quote_literal 函数不适用于 8.4 安装的 postgres 上的特定数据库。

这是我在新测试数据库上的结果:

select quote_literal(42);
 quote_literal 
---------------
 '42'
(1 row)

现在在目标数据库上也是如此

select quote_literal(42);
ERROR:  function quote_literal(integer) is not unique
LINE 1: select quote_literal(42);
           ^
HINT:  Could not choose a best candidate function. You might need to add explicit type casts.

AIUI,quote_literal(anyvalue) 函数应该可以处理整数值,这似乎在第一次测试中得到了支持。

所以我认为 quote_literal 函数必须在这个数据库中被覆盖,但事实并非如此。我可以用特定的 quote_literal(integer) 函数覆盖它,但我不明白为什么我必须这样做。

问题是什么可能导致此特定数据库中的此功能失败,同时不影响新数据库?

4

2 回答 2

4

另一种可能性:有人添加了从文本到数据库的隐式转换。这是 8.3 中故意 BC 中断的常见解决方法。请参阅8.3、E.57.2 的发行说明。迁移到 8.3 版

演示:

regress=# \df quote_literal
                              List of functions
   Schema   |     Name      | Result data type | Argument data types |  Type  
------------+---------------+------------------+---------------------+--------
 pg_catalog | quote_literal | text             | anyelement          | normal
 pg_catalog | quote_literal | text             | text                | normal
(2 rows)
regress=# CREATE FUNCTION pg_catalog.text(integer) RETURNS text STRICT IMMUTABLE LANGUAGE SQL AS 'SELECT textin(int4out($1));';
CREATE FUNCTION
regress=# CREATE CAST (integer AS text) WITH FUNCTION pg_catalog.text(integer) AS IMPLICIT;
CREATE CAST
regress=# SELECT quote_literal(42);
ERROR:  function quote_literal(integer) is not unique
LINE 1: SELECT quote_literal(42);
               ^
HINT:  Could not choose a best candidate function. You might need to add explicit type casts.
regress=# 

这将解决它,但可能会破坏仍然依赖于演员表的其他代码:

regress=# DROP CAST (integer AS text);
DROP CAST
regress=# SELECT quote_literal(42);
 quote_literal 
---------------
 '42'
(1 row)
于 2012-11-07T12:02:41.280 回答
1

可能有人定义了另一个单参数quote_literal函数,其参数类型与赋值兼容integer,例如bigint.

psql中,连接并运行:

\df quote_literal

您会看到多个条目,如下所示:

regress=> \df quote_literal
                              List of functions
   Schema   |     Name      | Result data type | Argument data types |  Type  
------------+---------------+------------------+---------------------+--------
 pg_catalog | quote_literal | text             | anyelement          | normal
 pg_catalog | quote_literal | text             | text                | normal
 public     | quote_literal | text             | bigint              | normal
(3 rows)

你只想要第一个两个,在pg_catalog. 但是,我不能建议您这样做:

DROP FUNCTION public.quote_literal(bigint);

...因为您可能有期望它存在的代码。是时候去挖掘看看它在哪里使用了。玩得开心。

演示表明这可能是问题所在:

regress=> SELECT quote_literal(42);
 quote_literal 
---------------
 '42'
(1 row)

regress=> CREATE OR REPLACE FUNCTION quote_literal(bigint) RETURNS text AS 'SELECT ''borkborkbork''::text;' LANGUAGE sql;
CREATE FUNCTION
regress=> SELECT quote_literal(42);
ERROR:  function quote_literal(integer) is not unique
LINE 1: SELECT quote_literal(42);
               ^
HINT:  Could not choose a best candidate function. You might need to add explicit type casts.
regress=> 
于 2012-11-07T11:40:55.960 回答