AnA*_*ice 4 postgresql substring postgresql-9.1
我正在使用PostgreSQL和Rails 3.2.我的一个db迁移具有以下内容:
execute <<-SQL
CREATE INDEX users_multi_idx
ON users (lower(left(fname, 1)), fname)
WHERE deleted_at IS NULL;
SQL
Run Code Online (Sandbox Code Playgroud)
在某些dbs上迁移时,我们收到以下错误:
== AddFnameIndexToUsers: migrating ===========================================
-- execute(" CREATE INDEX users_multi_idx\n ON users (lower(left(fname, 1)), fname)\n WHERE deleted_at IS NULL;\n")
rake aborted!
An error has occurred, this and all later migrations canceled:
PG::Error: ERROR: function left(character varying, integer) does not exist
LINE 2: ON users (lower(left(fname, 1)), fname)
^
HINT: No function matches the given name and argument types. You might need to add explicit type casts.
: CREATE INDEX users_multi_idx
ON users (lower(left(fname, 1)), fname)
WHERE deleted_at IS NULL;
Run Code Online (Sandbox Code Playgroud)
奇怪的是,这不会发生在所有dbs上,只有一些(暂存).关于这个索引执行有什么问题的任何建议?
你把它标记为postgresql-9.1,但我强烈怀疑你在这里处理旧版本.当你问:你得到什么:
SELECT version();
Run Code Online (Sandbox Code Playgroud)
left()随9.1版推出.对于旧版本替代left(fname, 1):
substr(fname, 1, 1)
Run Code Online (Sandbox Code Playgroud)
如果由于某种原因(例如@Wize)无法修改查询,则可以在9.1之前为旧版本创建插件替换:
CREATE OR REPLACE FUNCTION public.left(text, int)
RETURNS text LANGUAGE sql STABLE COST 30 AS
'SELECT substr($1, 1, $2)';
Run Code Online (Sandbox Code Playgroud)
这通常不会在版本升级后引起冲突,因为默认模式搜索路径pg_catalog之前(隐式)具有public,因此一旦系统函数退出,用户定义的函数就会停止运行 - 除非明确地进行模式限定.但无论如何,你应该在版本升级后删除它.
我添加了这个,建议对@Wize提供的一些改进:
使用LANGUGAE sql(非plpgsql)有多种原因:
使用函数波动率STABLE,这是合适的并有助于提高性能.
使用$n符号来引用函数参数,因为旧版本中的SQL函数不支持参数名称.
public显式创建模式中的函数.否则,它可能在当前用户"私有"架构中创建,而不适用于其他用户.根据您的架构搜索路径,这应该是最好的.
使用数据类型text,这是默认的字符类型,与之相同left()或substr()返回.也适用varchar.
| 归档时间: |
|
| 查看次数: |
7298 次 |
| 最近记录: |