position函数在标准sql及postgresql中语法为position('sub' in str),返回子串首次出现位置(从1开始),未找到返回0;mysql不支持,需用locate或instr;sql server用charindex,oracle用instr,均不兼容position。

POSITION 函数在标准 SQL 中用于返回子字符串在主字符串中首次出现的起始位置(从 1 开始计数),但它的行为和可用性因数据库而异,直接照搬可能报错或返回意外结果。
POSITION 在 PostgreSQL 和标准 SQL 中怎么用
PostgreSQL 完全支持 POSITION,语法为 POSITION(substring IN string),注意参数顺序是「子串 IN 主串」,且不支持第三个参数或模式匹配。
- 正确写法:
SELECT POSITION('world' IN 'hello world');→ 返回7 - 错误写法:
POSITION('hello world', 'world')(MySQL 风格)会报错 - 空子串或未找到时返回
0,不是NULL - 区分大小写:
POSITION('WORLD' IN 'hello world')返回0
MySQL 不支持 POSITION,该用 LOCATE 还是 INSTR
MySQL 没有 POSITION 函数,强行使用会提示 FUNCTION xxx.POSITION does not exist。必须改用 LOCATE 或 INSTR,二者功能接近但参数顺序相反:
-
LOCATE(substring, string[, position]):子串在前,主串在后,可选起始偏移(从 1 开始) -
INSTR(string, substring):主串在前,子串在后,不支持偏移 - 都返回从 1 开始的位置,未找到返回
0;例如LOCATE('o', 'hello')→5,INSTR('hello', 'o')→5 - 注意:MySQL 的
LOCATE支持第三个参数(跳过前 N 个字符),POSITION在任何方言中都不支持该能力
SQL Server 和 Oracle 怎么办
SQL Server 和 Oracle 均不支持 POSITION。它们各自使用:
- SQL Server:用
CHARINDEX(substring, string[, start_location]),返回从 1 开始的位置,未找到返回0 - Oracle:用
INSTR(string, substring[, position[, occurrence]]),默认从开头找第一次出现,支持指定第几次匹配和起始位置 - 三者共同点:都从 1 计数,不是 0;都区分大小写(除非启用大小写不敏感排序规则)
- 差异点:
INSTR在 Oracle 中可定位第 N 次出现,CHARINDEX和POSITION都只能找第一次
跨数据库写法不可行,迁移时最容易漏掉这点
没有一种写法能同时在 PostgreSQL、MySQL、SQL Server、Oracle 中运行。哪怕只是把 POSITION('x' IN y) 改成 LOCATE('x', y),在 PostgreSQL 里也会因函数不存在而失败。
如果代码要兼容多库,要么用条件化 SQL(如通过应用层判断方言再拼接),要么统一抽象为应用逻辑处理——数据库函数的“同名不同形”在这里特别典型,别指望靠换个别名就一劳永逸。










