MsSql2005 CharIndex的用法

CHARINDEX函数详解
本文详细介绍了CHARINDEX函数的使用方法及注意事项,包括如何查找字符在字符串中的位置、如何使用第三个参数设置查找起始位置等。此外,还解释了函数对于不同数据类型和排序规则的处理方式。
 CHARINDEX函数返回字符或者字符串在另一个字符串中的起始位置。CHARINDEX函数调用方法如下:

       CHARINDEX ( expression1 , expression2 [ , start_location ] )

       Expression1是要到expression2中寻找的字符中,start_location是CHARINDEX函数开始在expression2中找expression1的位置。

       CHARINDEX函数返回一个整数,返回的整数是要找的字符串在被找的字符串中的位置。假如CHARINDEX没有找到要找的字符串,那么函数整数“0”。让我们看看下面的函数命令执行的结果:

      CHARINDEX('Zhang', 'Devil_Zhang')

      这个函数命令将返回在“Devil_Zhangr”中“Zhang”的起始位置,在这个例子中,CHARINDEX函数将返回“Z”在“Devil_Zhang”中的位置7。
  接下来,我们看这个CHARINDEX命令:

      CHARINDEX('zhangsns', 'Devil_Zhang')      

  在这个例子中,CHARINDEX返回0,因为字符串“zhangsns” 不能在“Devil_Zhang”中被找到。

  此时,我们再尝试一下CharIndex中的第三个参数【start_location】,如下:

  CHARINDEX('zhang', 'Devil_Zhang')----->7

  CHARINDEX('zhang', 'Devil_Zhang',9)------>0

   【因为设置了被查字符串的起始位置为9,即“ang",所以,返回的是0】

  需要注意的是:

  1、如果 expression1 或 expression2 之一是 Unicode 数据类型(nvarchar 或 nchar)而另一个不是,则将另一个转换为 Unicode 数据类型。CHARINDEX 不能与 textntext 和 image 数据类型一起使用。

  2、如果 expression1 或 expression2 之一为 NULL,并且数据库兼容级别为 70 或更高,则 CHARINDEX 将返回 NULL。如果数据库兼容级别为 65 或更低,则 CHARINDEX 将仅在 expression1 和 expression2 都为 NULL 时才返回 NULL 值。

  3、如果在 expression2 内找不到 expression1,则 CHARINDEX 返回 0。

  4、返回的开始位置从 1 开始,而非从 0 开始。

  5、查找的字符和被查的字符是不区分大小写的。

  针对下句:

  SELECT CHARINDEX ( 'Test', 'Das ist ein Test'  COLLATE Latin1_General_BIN);
     【CHARINDEX 将根据输入的排序规则执行比较操作。若要以指定排序规则进行比较,则可以使用 COLLATE 将显式排序规则应用于输入值。】

转载于:https://www.cnblogs.com/A2008A/archive/2011/03/11/1981116.html

<think>我们正在讨论SQLServer中的CHARINDEX函数。根据引用,CHARINDEX函数用于查找一个字符串(子字符串)在一个字符串(父字符串中的起始位置。如果找到,返回位置(从1开始计数);如果未找到,返回0。函数语法:CHARINDEX(expression1,expression2[,start_location])参数说明:-expression1:要查找的子字符串-expression2:父字符串(被搜索的字符串)-start_location:可选,指定开始搜索的位置,默认从1开始(即字符串开头)注意点:1.该函数区分大小写,除非使用不区分大小写的排序规则。2.当两个参数都是变量时,在某些情况下(如在触发器或存储过程中)可能会遇到问题(如引用[2]所述),建议其中一个参数使用常量,但这不是必须的,可能是特定环境的问题。我们将通过几个示例来展示CHARINDEX用法。示例1:基本用法查找字符串'abc'在字符串'123abc456'中的位置。结果应为4(因为'a'出现在第4个字符位置)。示例2:使用起始位置从第5个字符开始查找'abc'在'123abc456abc'中的位置。结果应为10(因为第二个'abc'从第10个字符开始)。示例3:判断是否包含通常我们利用返回值是否大于0来判断父字符串中是否包含子字符串。例如:SELECT*FROMtableWHERECHARINDEX('abc',column)>0示例4:结合其他函数使用(如引用[3]中的REVERSE函数)例如,查找电话号码(phone)倒数第3位是否为2,倒数第2位是否为6,倒数第1位是否为偶数。他们使用了REVERSE函数字符串反转,然后使用SUBSTRING函数取特定位置字符,再判断。我们可以用CHARINDEX结合REVERSE吗?但这里使用SUBSTRING更直接,因为要取特定位置字符。示例5:在触发器中使用的注意事项(引用[2])在触发器或存储过程中,如果两个参数都是变量,可能会遇到问题。如果遇到问题,可以尝试将子字符串写为常量(如果可能)或检查变量内容是否正确。示例6:区分大小写如果数据库的排序规则区分大小写,那么CHARINDEX('A','abc')将返回0。如果不区分,则可能返回1(如果子字符串是'a'的话)。下面我们用具体的SQL语句来演示:示例1:基本用法SELECTCHARINDEX('abc','123abc456')ASPosition;示例2:使用起始位置SELECTCHARINDEX('abc','123abc456abc',5)ASPosition;示例3:判断是否包含--假设有一个表Products,有一个列ProductName,我们想查找包含'Bike'的产品SELECT*FROMProductsWHERECHARINDEX('Bike',ProductName)>0;示例4:结合REVERSE--例如,我们想查找电话号码(phone)中倒数第二个字符是'6'的记录--方法1:使用REVERSE和SUBSTRING(如引用[3])SELECT*FROMtab1WHERESUBSTRING(REVERSE(phone),2,1)='6';--方法2:使用CHARINDEX?这里并不适用,因为我们要的是特定位置字符,不是查找子串的位置。但是,我们可以用CHARINDEX来查找某个字符最后一次出现的位置吗?可以结合REVERSE来实现:--查找字符串中最后一个'.'的位置--思路:反转字符串,找到第一个'.'的位置,然后用原字符串长度+1减去这个位置DECLARE@strVARCHAR(100)='www.example.com';SELECTLEN(@str)+1-CHARINDEX('.',REVERSE(@str))ASLastDotPosition;示例5:在触发器中的使用(根据引用[2]的注意)--假设在触发器中,我们想检查插入的数据中某个字段是否包含某个字符串,为了避免问题,可以将子字符串写为常量IFCHARINDEX('error',@Description)>0RAISERROR('Descriptioncontainserror',16,1);示例6:区分大小写--如果数据库排序规则区分大小写,那么以下查询返回0:SELECTCHARINDEX('A','abc')COLLATESQL_Latin1_General_CP1_CS_AS;--如果不区分,则可能返回1(如果实际是'a')?但是注意,这里是大写'A'和小写'abc',所以返回0。外,引用[4]详细说明了语法。总结:CHARINDEX一个常用的字符串查找函数返回字符串起始位置。它常用于WHERE子句中来过滤包含特定字符串的记录,或者用于字符串的定位操作。注意事项:-位置从1开始计数。-未找到返回0。-可以指定起始位置。-注意排序规则对大小写敏感性的影响。最后,根据用户要求,生成相关问题。</think>### SQL Server CHARINDEX 函数详解与用法示例 #### 📌 核心功能 `CHARINDEX` 函数用于查找子字符串在目标字符串中的**起始位置**(从1开始计数)。若未找到则返回0,是 SQL Server 中实现字符串包含判断的关键函数[^1][^4]。 --- #### ⚙️ 语法结构 ```sql CHARINDEX( expression1, expression2 [ , start_location ] ) ``` - **`expression1`**:要查找的子字符串(必需) - **`expression2``**:被搜索的目标字符串(必需) - **`start_location`**:搜索起始位置(可选,默认值=1)[^4] --- #### 🔍 基础用法示例 ##### 示例1:基本定位(区分大小写) ```sql SELECT CHARINDEX('SQL', 'Learn SQL Server') AS Position; -- 返回:7('SQL'从第7个字符开始) ``` ##### 示例2:指定起始位置 ```sql SELECT CHARINDEX('a', 'Banana', 3) AS Position; -- 返回:4(从第3位开始搜索,第2个'a'的位置) ``` ##### 示例3:判断字符串包含 ```sql SELECT * FROM Products WHERE CHARINDEX('Pro', ProductName) > 0; -- 替代Contains功能[^1] ``` ##### 示例4:未找到子字符串 ```sql SELECT CHARINDEX('Python', 'SQL Server') AS Position; -- 返回:0(未找到) ``` --- #### 💡 高级应用场景 ##### 场景1:结合 `REVERSE` 反向搜索(引用[3]) ```sql -- 检查电话号码倒数第3位是否为'2' SELECT * FROM Users WHERE SUBSTRING(REVERSE(Phone), 3, 1) = '2'; ``` ##### 场景2:提取子字符串 ```sql DECLARE @url VARCHAR(100) = 'https://example.com/page'; SELECT SUBSTRING(@url, CHARINDEX('//', @url) + 2, CHARINDEX('.', @url) - CHARINDEX('//', @url) - 2) AS Domain; -- 返回:example ``` ##### 场景3:避免游标处理(引用[2]经验) ```sql -- 推荐:子字符串用常量,目标字符串用变量 DECLARE @searchStr VARCHAR(10) = 'Error'; SELECT * FROM Logs WHERE CHARINDEX('Error', @searchStr) > 0; -- 常量在前更稳定[^2] ``` --- #### ⚠️ 关键注意事项 1. **大小写敏感性** 结果受数据库排序规则影响,可通过 `COLLATE` 指定: ```sql SELECT CHARINDEX('a', 'ABC' COLLATE Latin1_General_CS_AS); -- 返回0(区分大小写) ``` 2. **参数类型限制** - 仅支持 `CHAR`, `VARCHAR`, `NCHAR`, `NVARCHAR` 类型 - 若参数为 `TEXT`,需先转换为 `VARCHAR(MAX)` 3. **变量使用建议** 在触发器/存储过程中,优先将子字符串声明为常量(避免引用[2]中的执行问题) 4. **性能优化** 避免在大型表上直接使用,可先过滤: ```sql SELECT * FROM LargeTable WHERE LEN(Description) > 10 -- 先减少数据量 AND CHARINDEX('urgent', Description) > 0; ``` --- #### 🔄 与其他函数对比 | 函数 | 功能描述 | 与CHARINDEX区别 | |---------------------|----------------------------|------------------------------| | **`PATINDEX`** | 支持通配符匹配 | 可用`%`模糊搜索(如`'%SQL%'`)| | **`SUBSTRING`** | 截取子字符串 | 依赖CHARINDEX定位起始点 | | **`LEFT`/`RIGHT`** | 从两端截取字符串 | 无法动态定位中间内容 | --- ### 相关问题 1. 如何在 `CHARINDEX` 中实现不区分大小写的搜索? 2. 如何用 `CHARINDEX` 和 `SUBSTRING` 联合提取两个特定字符间的字符串? 3. `CHARINDEX` 与 `PATINDEX` 在性能上有何差异? 4. 当子字符串重复出现时,如何获取所有位置而不仅是第一个? 5. 在超长字符串(如`VARCHAR(MAX)`)中使用 `CHARINDEX` 有哪些性能风险? > 引用说明:本文示例基于 SQL Server 语法实现,其他数据库(如 MySQL 的 `LOCATE`)功能类似但语法不同[^1][^2][^3][^4]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值