PATINDEX和SUBSTRING没有返回正确的值

时间:2018-01-03 14:55:32

标签: sql sql-server sql-server-2008 tsql

我有以下查询:

select [Service Item Value],
  SUBSTRING
  (
    [Service Item Value],
    PATINDEX('%[3][C][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]%', 
      [Service Item Value]),
    10
  ) AS [Circuit Reference]
FROM [dbo].[3c_and_2c_Report_Multiple_customers];

查询应查找服务项值列中的任何字符串,并提取任何长度为10个字符且以3C开头的字符串。它正在这样做(查看查询的最后结果),但是,当没有模式匹配时,它只返回它想要的任何内容

Service Item Value                     Circuit Reference
38159 (Cease) & 38160 (Re-Provide)          38159 (Ce
384K                                        384K
3925 bundle no. 1230                        3925 bund
3C00156746                                  3C00156746
P752480A,C72/217777*3C00190634,             3C00190634
P0638887A, C72/23872 * 3C00193454           3C00193454
(C72/29814 * P0647973A)>3C00231114 *        3C00231114`

基本上,如果没有模式匹配,请将Circuit Reference列留空。

3 个答案:

答案 0 :(得分:6)

如果没有匹配,

PATINDEX将返回0;如果第一个字符匹配,则返回1 ...(第二个字符为2等)

SUBSTRING将接受0作为第二个 start 参数。

所以你基本上允许失败的PATINDEX仍然返回一个子字符串。

也许使用CASE表达式来捕获PATINDEX

的零回报
CASE WHEN PATINDEX('%[3][C][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]%', [Service Item Value]) = 0 THEN ''
ELSE
SUBSTRING([Service Item Value],PATINDEX('%[3][C][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]%', [Service Item Value]),10) 
END AS [Circuit Reference]

答案 1 :(得分:2)

也许是另一种选择

示例

Select *
      ,[Circuit Reference]=substring([Service Item Value],patindex('%3C[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]%',[Service Item Value]+'3C0000000000'),10)
 From  YourTable

<强>返回

Service Item Value                     Circuit Reference
38159 (Cease) & 38160 (Re-Provide)  
3845 cisco router   
384K    
384K    
3925 bundle no. 1230    
3925 router; bundle :1230   
3C00156746                              3C00156746
P752480A,C72/217777*3C00190634,         3C00190634
P0638887A, C72/23872 * 3C00193454       3C00193454
(C72/29814 * P0647973A)>3C00231114 *    3C00231114

答案 2 :(得分:1)

它没有返回它想要的“随便”,它的回复正是你告诉它的。

如果PATINDEX找不到它正在查找的模式,它将返回值0.这意味着,有效地,您的表达式变为SUBSTRING([Service Item Value],0,10),因此您将获得最左边的10个字符

如果您不想返回值,请使用CASE:

SELECT [Service Item Value],
       CASE WHEN PATINDEX('%[3][C][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]%', [Service Item Value]) > 0 THEN SUBSTRING([Service Item Value],PATINDEX('%[3][C][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]%', [Service Item Value]),10) END AS [Circuit Reference],
FROM [dbo].[3c_and_2c_Report_Multiple_customers];