mysql的instr(str, substr)从1开始返回子串首次位置,未找到返回0;注意参数顺序与locate相反,且0是正常结果需显式判断>0;postgresql用position('substr' in str)或strpos(str, substr)替代;oracle支持4参数灵活查找;sql server用charindex(substr, str)。

INSTR函数在MySQL里怎么用?
MySQL的INSTR函数从1开始计数,返回子串首次出现的位置,没找到返回0。它不区分大小写(除非字段是binary或启用了case-sensitive collation),这点和LOCATE行为一致,但参数顺序相反——INSTR(str, substr),先主串后子串。
常见错误是把参数顺序记成LOCATE那样(LOCATE(substr, str)),结果总返回0或报错;另一个坑是误以为返回0表示“没找到”是异常,其实这是正常逻辑结果,不能直接用于WHERE条件判断而不加> 0。
- 查“apple”中“p”的位置:
INSTR('apple', 'p')→ 返回2 - 查不存在的子串:
INSTR('hello', 'xyz')→ 返回0 - 配合
WHERE使用时要显式判断:WHERE INSTR(name, 'admin') > 0
PostgreSQL有没有INSTR?替换成什么?
PostgreSQL没有INSTR函数,最直接的替代是POSITION,语法为POSITION('substr' IN str),同样从1开始,找不到返回0。注意单引号必须包裹子串,且IN是关键字,不能省略。
如果需要兼容MySQL写法或做跨数据库迁移,也可以用STRPOS(str, substr),参数顺序和MySQL的INSTR一致,返回值语义也相同,更少出错。
-
POSITION('lo' IN 'hello')→4 -
STRPOS('hello', 'lo')→4 - 别写
POSITION('lo' IN 'hello'::text)——类型强制一般不需要,除非字段是bytea或无类型字面量
Oracle的INSTR为什么经常多出一个参数?
Oracle的INSTR支持最多4个参数:INSTR(str, substr[, start_position[, occurrence]])。前两个必填,后两个可选。默认从开头找第1次出现;设start_position为负数会从末尾反向查找;occurrence指定找第几次匹配(比如找第二个逗号)。
这个灵活性是双刃剑:不传后两个参数时行为和MySQL/PostgreSQL一致;但一旦漏掉中间参数又写了最后一个,Oracle会把第三个当作start_position、第四个当作occurrence,容易误判起始位置。
-
INSTR('a,b,c,d', ',', 1, 2)→ 找第2个逗号,返回5 -
INSTR('a,b,c,d', ',', -1)→ 从末尾往前找第一个逗号,返回5 - 错误写法:
INSTR('a,b,c,d', ',', 2)→ 其实是在位置2之后找第1个逗号,不是“找第2个”,别混淆
SQL Server用户别硬套INSTR,该用CHARINDEX
SQL Server用CHARINDEX,语法是CHARINDEX(substr, str[, start_location]),和Oracle的前两个参数顺序一样,但默认从1开始,找不到返回0。注意它不支持“找第n次出现”,也不支持反向搜索。
容易踩的坑是:字符串字面量必须用单引号,且CHARINDEX对Unicode字符串(nvarchar)敏感——如果substr是普通varchar而str是nvarchar,可能因隐式转换失败返回0;稳妥做法是统一加N''前缀。
-
CHARINDEX(',', 'a,b,c')→2 -
CHARINDEX(N',', N'a,b,c')→ 明确Unicode,避免隐式转换问题 - 想跳过前n个字符再查?用
CHARINDEX(',', SUBSTRING(str, n+1, LEN(str))) + n,别直接改第三个参数指望它跳过
WHERE或CASE逻辑时最容易被忽略。











