2017-04-11 76 views
0

我一直在试图收集下面两个字符串之间的文本,但并非所有的行都包含任一字符串,并且它返回以下错误;SQL选择两个字符串之间的字符串

消息537,级别16,状态5,第22行
传递给左或子字符串函数 无效的长度参数

我似乎无法修改代码,允许领域无论何处字符串不包含在选择列中,并且如果是这种情况,则返回Null。

DECLARE @FirstPatn CHAR(3) 
DECLARE @SecondPatn CHAR(3) 

SET @FirstPatn = 'EMR' 
SET @SecondPatn = ' - ' 

SELECT 
    @start = PATINDEX('%' + @FirstPatn + '%', ActionDescription), 
    @end = PATINDEX('%' + @secondPatn + '%', ActionDescription) 
FROM 
    Temp.TicketActions 

SELECT 
    SUBSTRING(ActionDescription, @start + LEN(@firstpatn), (@end - @start) - LEN(@secondpatn)) 
FROM 
    Temp.TicketActions 

请在下面找到一些示例数据;

Arran LBS - EMR00524 - Packet loss 

Email: RE: Arran LBS - EMR00524 - No Sync (connection affected: [email protected]) [#3314184] (11/06/15 17:03) 

RE: Arran LBS - EMR00524 - No Sync 

RE: Arran LBS - EMR00524 - No Syn (connection affected: [email protected]) 

Automatic Unpark 

Broadband Regrade 

This Ticket has been resolved. 

domain query 
+0

能否请您提供从TickeActions表中的一些样本记录?了解情景会有所帮助。 – PJS

+1

你可以提供样本数据和你的预期输出吗?并标记您使用的数据库:SQL Server或MySql或Oracle .... –

+0

无论您的情况如何,您都有一个大问题:第一个“SELECT”语句为'@ start'和'@ end'变量指定一个固定值。 –

回答

0

最大的问题是,你得到的@SecondPatnpatindex,即使@FirstPatn之前发生的。这是我们错误的根源。这是因为所有的包含@FirstPatn的例子记载有@SecondPatn@FirstPatn

第一次出现之前发生,我们希望我们的终点设置为@SecondPatn开始位置,但只有当它被@FirstPatn后发现的。

查询中的另一个问题在Giorgos的评论中提到 - @start@end在您的查询中是固定值。这些需要改变,因为我们正在考虑的字符串将逐行更改。

本示例使用您提供的示例数据。它返回我们正在查找的字符串和代码。我增加了我们正在寻找的一个字符串的长度,以显示这个字符串的长度可变。你可以运行这个来测试,然后修改来处理你的模式。你没有指定所需的结果,所以我假设根据你的查询。

设置:

declare @test table (
id int, 
ActionDescription varchar(max) 
) 

insert into @test 
values 
(1, 'Arran LBS - EMR00524 - Packet loss'), 
(2, 'Email: RE: Arran LBS - EMR00524 - No Sync (connection affected: [email protected]) [#3314184] (11/06/15 17:03)'), 
(3, 'RE: Arran LBS - EMR0052467 - No Sync'), 
(4, 'RE: Arran LBS - EMR00524 - No Syn (connection affected: [email protected])'), 
(5, 'Automatic Unpark'), 
(6, 'Broadband Regrade'), 
(7, 'This Ticket has been resolved.'), 
(8, 'domain query') 

查询:

declare @FirstPatn char(3) 
declare @SecondPatn char(3) 

set @FirstPatn = 'EMR' 
set @SecondPatn = ' - '; 

select sub.ActionDescription, 
     sub.TicketActions 
from (
    select 
     ActionDescription, 
      -- set value to null when first pattern not found 
     case when patindex('%' + @FirstPatn + '%', ActionDescription) = 0 
      then null 
      else 
       substring(    
       ActionDescription, 
        --start position is after our first pattern 
       (patindex('%' + @FirstPatn + '%', ActionDescription)) + len(@FirstPatn), 
        -- end position is start position of second pattern, only when second pattern is found AFTER first pattern 
       patindex('%' + @secondPatn + '%',right(ActionDescription, len(ActionDescription) - (patindex('%' + @FirstPatn + '%', ActionDescription) + len(@FirstPatn) - 1)))   
      ) 
     end TicketActions 
    from @test 
)sub 
where sub.TicketActions is not null 

结果:

+---------------+----------------------------------------------------------------------------------------------------------------+ 
| TicketActions |            ActionDescription            | 
+---------------+----------------------------------------------------------------------------------------------------------------+ 
|  00524 | Arran LBS - EMR00524 - Packet loss                    | 
|  00524 | Email: RE: Arran LBS - EMR00524 - No Sync (connection affected: [email protected]) [#3314184] (11/06/15 17:03) | 
|  0052467 | RE: Arran LBS - EMR0052467 - No Sync                   | 
|  00524 | RE: Arran LBS - EMR00524 - No Syn (connection affected: [email protected])         | 
+---------------+----------------------------------------------------------------------------------------------------------------+ 

要返回空值时,我们的串没有找到,只需删除外部查询:

declare @FirstPatn char(3) 
declare @SecondPatn char(3) 

set @FirstPatn = 'EMR' 
set @SecondPatn = ' - '; 

select 
    -- set value to null when first pattern not found 
    case when patindex('%' + @FirstPatn + '%', ActionDescription) = 0 
     then null 
     else 
      substring(    
      ActionDescription, 
      --start position is after our first pattern 
      (patindex('%' + @FirstPatn + '%', ActionDescription)) + len(@FirstPatn), 
      -- end position is start position of second pattern, only when second pattern is found AFTER first pattern 
      patindex('%' + @secondPatn + '%',right(ActionDescription, len(ActionDescription) - (patindex('%' + @FirstPatn + '%', ActionDescription) + len(@FirstPatn) - 1)))   
      ) 
    end TicketActions, 
    ActionDescription 
from @test 

回报

+---------------+----------------------------------------------------------------------------------------------------------------+ 
| TicketActions |            ActionDescription            | 
+---------------+----------------------------------------------------------------------------------------------------------------+ 
| 00524   | Arran LBS - EMR00524 - Packet loss                    | 
| 00524   | Email: RE: Arran LBS - EMR00524 - No Sync (connection affected: [email protected]) [#3314184] (11/06/15 17:03) | 
| 0052467  | RE: Arran LBS - EMR0052467 - No Sync                   | 
| 00524   | RE: Arran LBS - EMR00524 - No Syn (connection affected: [email protected])         | 
| NULL   | Automatic Unpark                        | 
| NULL   | Broadband Regrade                        | 
| NULL   | This Ticket has been resolved.                     | 
| NULL   | domain query                         | 
+---------------+----------------------------------------------------------------------------------------------------------------+ 
相关问题