Postgresql PG::Error:Error:函数left(字符变化,整数)不存在

Postgresql PG::Error:Error:函数left(字符变化,整数)不存在,postgresql,substring,postgresql-9.1,Postgresql,Substring,Postgresql 9.1,我正在使用PostgreSQL和Rails 3.2。my db迁移之一具有以下功能: execute <<-SQL CREATE INDEX users_multi_idx ON users (lower(left(fname, 1)), fname) WHERE deleted_at IS NULL; SQL 奇怪的是,这并不是发生在所有的dbs上,只是一些(登台)。关于这个索引执行的错误有什么建议吗?您标记了它,但我强烈怀疑您正在处理一个旧版本。当你问到: SELE

我正在使用PostgreSQL和Rails 3.2。my db迁移之一具有以下功能:

execute <<-SQL
  CREATE INDEX users_multi_idx
  ON users (lower(left(fname, 1)), fname)
  WHERE deleted_at IS NULL;
SQL
奇怪的是,这并不是发生在所有的dbs上,只是一些(登台)。关于这个索引执行的错误有什么建议吗?

您标记了它,但我强烈怀疑您正在处理一个旧版本。当你问到:

SELECT version();
是在9.1版中引入的。对于较旧的版本,将左侧(fname,1)替换为:

substr(fname, 1, 1)
替代品 如果由于某种原因()无法修改查询,则可以为9.1之前的旧版本创建插入式替换:

CREATE OR REPLACE FUNCTION public.left(text, int)
 RETURNS text LANGUAGE sql STABLE COST 30 AS
'SELECT substr($1, 1, $2)';
这通常不会在版本升级后导致冲突,因为默认值在
public
之前有
pg_catalog
(隐式),因此用户定义的函数在系统函数退出后即停止运行,除非模式明确限定。但无论如何,在版本升级之后,您应该将其删除

我添加了这一点,以建议对@Wize提供的内容进行一些改进:

  • 出于多种原因使用
    Language sql
    (而不是
    plpgsql
    ):

    • 更短,更简单
    • ,因此您可能会遇到另一个问题,就像您试图解决的问题一样
    • 我介绍的简单函数可以是,它可以在较大查询的上下文中提高性能
  • 使用函数volatility
    STABLE
    ,这是适当的,有助于提高性能

  • 使用
    $n
    符号引用函数参数,因为旧版本的SQL函数不支持参数名称

  • public
    模式中显式创建函数。否则它可能在当前用户的“私有”模式中创建,而不适用于其他用户。根据您的不同,这将为您提供最佳服务

  • 使用数据类型
    text
    ,这是默认字符类型,与
    left()
    substr()
    返回相同。也适用于
    varchar


只需为9.1之前的Posgres版本创建以下函数

CREATE OR REPLACE FUNCTION left(s character varying,i int)
RETURNS character varying AS
$BODY$
BEGIN
  return substr(s, 1, i);
 END
$BODY$
  LANGUAGE plpgsql VOLATILE
  COST 100;

谢谢Erwin,这就是我们让使用不同版本postgresI的会员回答的问题,因为我无法更改库中的代码。因此,这可能会帮助其他处于类似情况的人。这是有用的,但我认为还有改进的余地。您可能会对我在答案中添加的备选方案感兴趣。有人知道我为什么会出现错误:语法错误或接近“成本”为什么要创建此函数?如果我去掉不稳定的成本100,它就消失了;
CREATE OR REPLACE FUNCTION left(s character varying,i int)
RETURNS character varying AS
$BODY$
BEGIN
  return substr(s, 1, i);
 END
$BODY$
  LANGUAGE plpgsql VOLATILE
  COST 100;