在SQL查询处理字符串数据时,查找指定子串在主字符串中的起始位置是常见需求,INSTR和CHARINDEX是两个常用的实现函数,二者语法和适用场景有所不同。

INSTR函数的基本用法
INSTR函数主要用于返回子串在主字符串中第一次出现的位置,在Oracle、MySQL等数据库中均有支持,不同数据库的语法存在细微差异。
Oracle中的INSTR语法
Oracle的INSTR函数完整语法为INSTR(string, substring, start_position, occurrence),其中start_position是可选参数,表示开始查找的位置,默认为1;occurrence是可选参数,表示返回第几次出现的位置,默认为1。
-- 查找'hello world'中'world'第一次出现的位置,结果为7
SELECT INSTR('hello world', 'world') AS position FROM DUAL;
-- 从位置2开始查找'l'第一次出现的位置,结果为3
SELECT INSTR('hello world', 'l', 2) AS position FROM DUAL;
-- 查找'l'第二次出现的位置,结果为4
SELECT INSTR('hello world', 'l', 1, 2) AS position FROM DUAL;
MySQL中的INSTR语法
MySQL的INSTR函数语法更简单,仅支持两个参数:INSTR(string, substring),返回子串第一次出现的位置,若不存在则返回0。
-- 查找'test_string'中'string'的位置,结果为6
SELECT INSTR('test_string', 'string') AS position;
-- 子串不存在时返回0
SELECT INSTR('test_string', 'abc') AS position;
CHARINDEX函数的基本用法
CHARINDEX函数是SQL Server中用于查找子串位置的函数,语法为CHARINDEX(substring, string, start_position),start_position为可选参数,默认从第一位开始查找,子串不存在时返回0。
-- 查找'SQL Server示例'中'Server'的位置,结果为5
SELECT CHARINDEX('Server', 'SQL Server示例') AS position;
-- 从位置6开始查找'S'的位置,结果为8
SELECT CHARINDEX('S', 'SQL Server示例', 6) AS position;
-- 子串不存在时返回0
SELECT CHARINDEX('abc', 'SQL Server示例') AS position;
两者的差异对比
| 对比项 | INSTR函数 | CHARINDEX函数 |
|---|---|---|
| 适用数据库 | Oracle、MySQL等 | SQL Server |
| 参数数量 | 最多4个(不同数据库有差异) | 最多3个 |
| 子串不存在返回值 | Oracle返回0,MySQL返回0 | 返回0 |
| 位置起始值 | 从1开始计数 | 从1开始计数 |
实际场景应用示例
假设有一张用户表user_info,其中email字段存储用户邮箱,需要查找所有邮箱域名是ipipp.com的用户,可以通过子串位置判断实现。
Oracle/MySQL实现
-- MySQL中使用INSTR函数查找ipipp.com的位置,大于0说明包含该域名 SELECT * FROM user_info WHERE INSTR(email, 'ipipp.com') > 0; -- Oracle中同样可以使用INSTR实现 SELECT * FROM user_info WHERE INSTR(email, 'ipipp.com') > 0;
SQL Server实现
-- 使用CHARINDEX函数查找ipipp.com的位置
SELECT * FROM user_info WHERE CHARINDEX('ipipp.com', email) > 0;
注意事项
- 两个函数均对大小写敏感,若需要不区分大小写查找,可先使用
LOWER或UPPER函数将字符串统一大小写再查找。 - 位置计数是从1开始的,而非从0开始,这一点和很多编程语言的字符串索引不同,使用时需要注意。
- 如果主字符串或者子串为NULL,两个函数的返回值在不同数据库中可能有差异,建议提前处理NULL值。
提示:如果需要兼容多种数据库,建议先确认目标数据库的字符串函数支持情况,再选择合适的函数实现子串位置查找功能。
SQLINSTR函数CHARINDEX函数子串查找修改时间:2026-06-28 17:57:14