2

我在一个 SQL 表中工作,其中一串信息存储在每个高级对象的单个列/行中。此列存储有关它们包含哪些基础对象的信息,每个子对象由 [Report] Report1.... [Report] Report2... 等标签表示,贯穿整个文本。有很多底层对象和标签,我需要能够只提取 [Report] 标签之后的值。

表结构

|对象ID|对象文本|

| 1 | [报告] 报告 1 [日期] 1 [报告] 报告 2 [日期] 2 [报告] 报告 3 [日期] 2|
| 2 | [报告] report5 [日期] 1 [报告] report8 [日期] 2 [报告] report3 [日期] 2|
| 3 | [报告] 报告 1 [日期] 1 [报告] 报告 2 [日期] 2 [报告] 报告 2 [日期] 2|


我不确定如何执行此操作,虽然我可以使用 CharIndex() 和 substring() 来接收第一个 [Report] 标记和紧随其后的值,但我不知道如何从每一行获取所有值。

选择 Substring(ObjectText,Charindex('[Report]', ObjectText) ,15) 作为来自 ObjectTable 的报告

我无法控制数据如何存储在表中,我个人不会在同一行中存储这么长的一串无关信息。

4

2 回答 2

0

Regarding splitting the data into arrays, hands down, one of the best sources of information on this for SQL Server:

http://www.sommarskog.se/arrays-in-sql.html

An excellent read across the board.

于 2013-08-27T21:55:27.837 回答
0

您可以尝试使用以下功能:

create function ftStringsBetween
(
    @str varchar(1000),
    @tagStart varchar(50),
    @tagEnd varchar(50)
)
returns table as
return
    with [10](N) as (select 1 union all select 1 union all select 1 union all select 1 union all select 1
        union all select 1 union all select 1 union all select 1 union all select 1 union all select 1),
    [1000](N) as (select 1 from [10] a, [10] b, [10] c),
    v3(N) as (select top (isnull(datalength(@str), 0)) row_number() over (order by @@spid) from [1000]),
    v4(N) as (select N + datalength(@tagStart) from v3 where charindex(@tagStart, @str, N) = N),
    v5(N1, N2) as (select N, N2=isnull(nullif(charindex(@tagEnd, @str, N), 0), datalength(@str) + 1) from v4)
    select Value = substring(@str, N1, N2-N1)
    from v5
GO

您可以将其应用于您的数据:

select o.ObjectID, rtrim(ltrim(fsb.Value)) Report
from Objects o
    outer apply ftStringsBetween(o.ObjectText, '[Report]', '[') fsb

这将导致:

ObjectID    Report
----------- -----------
1           report1
1           report2
1           report3
2           report5
2           report8
2           report3
3           report1
3           report2
3           report2

SQLFiddle 示例

于 2013-08-27T22:51:14.627 回答