SQL选择两个字符串之间的字符串

时间:2017-04-11 09:19:08

标签: sql-server string substring

我一直在尝试收集下面两个字符串之间的文本,但并非所有行都包含其中一个字符串,并返回以下错误;

  

Msg 537,Level 16,State 5,Line 22
  传递给LEFT或SUBSTRING函数的长度参数无效

我似乎无法修改代码以允许其中任何字符串未包含在select列中的字段,并且如果是这种情况则返回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: na2311@rTest..biz) [#3314184] (11/06/15 17:03)

RE: Arran LBS - EMR00524 - No Sync

RE: Arran LBS - EMR00524 - No Syn (connection affected: na23Test1@rnli.biz)

Automatic Unpark

Broadband Regrade

This Ticket has been resolved.

domain query

1 个答案:

答案 0 :(得分:0)

最大的问题是,即使patindex发生在@SecondPatn之前,您也会获得@FirstPatn @FirstPatn。这是我们错误的根本原因。这是因为包含@SecondPatn的所有示例记录在第一次出现@FirstPatn之前都出现@SecondPatn

我们希望将终点设置为@FirstPatn的起始位置,但仅限于@start之后的位置。

Giorgos在评论中提到了查询中的其他问题 - @enddeclare @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: na2311@rTest..biz) [#3314184] (11/06/15 17:03)'), (3, 'RE: Arran LBS - EMR0052467 - No Sync'), (4, 'RE: Arran LBS - EMR00524 - No Syn (connection affected: na23Test1@rnli.biz)'), (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: na2311@rTest..biz) [#3314184] (11/06/15 17:03) |
|      0052467  | RE: Arran LBS - EMR0052467 - No Sync                                                                           |
|        00524  | RE: Arran LBS - EMR00524 - No Syn (connection affected: na23Test1@rnli.biz)                                    |
+---------------+----------------------------------------------------------------------------------------------------------------+

<强>结果:

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: na2311@rTest..biz) [#3314184] (11/06/15 17:03) |
| 0052467       | RE: Arran LBS - EMR0052467 - No Sync                                                                           |
| 00524         | RE: Arran LBS - EMR00524 - No Syn (connection affected: na23Test1@rnli.biz)                                    |
| NULL          | Automatic Unpark                                                                                               |
| NULL          | Broadband Regrade                                                                                              |
| NULL          | This Ticket has been resolved.                                                                                 |
| NULL          | domain query                                                                                                   |
+---------------+----------------------------------------------------------------------------------------------------------------+

<强>返回

let tblVW:UITableView = UITableView(frame: viewForTableView.frame)
viewForTableView.addSubview(tblVW)
tblVW.delegate = self
tblVW.dataSource = self