选择表中每次出现的子字符串

时间:2014-10-01 17:24:49

标签: sql sql-server tsql sql-server-2005

我有一个帖子表:

PostID    PostHTML
===
1         '<p>Hello world! <img height=400 src="hello-world.jpg" height=600></p>'
2         'Bowties <img src="bowtie.gif" /> are cool. <img src="smiley.gif" />'
3         '<TABLE CELLSPACING=0 BORDER=0 CELLPADDING=0><TR><TD><B><FONT FACE="Arial"><P ALIGN="CENTER"><IMG SRC="FOO.GIF"></P></FONT></B></TD><TD><B><FONT FACE="Arial"><P ALIGN="CENTER"><IMG SRC="BAR.GIF"></P></FONT></B></TD><TD><B><FONT FACE="Arial"><P ALIGN="CENTER"><IMG SRC="INTERNET-CIRCA-1997.GIF"></P></FONT></B></TD></TR></TABLE>'
4         '<B><FONT FACE="Arial"><P>Did I mention this data is hideous?</P></B><P>&nbsp;</P></FONT>'

我需要选择此表中每个图像的src属性。到目前为止,我可以在每一行中首次出现:

select substring(
    posthtml,
    charindex('src="', posthtml),
    charindex('"', posthtml, charindex('src="', posthtml) + 5) - charindex('src="', posthtml) + 1
) from post

这导致:

src="hello-world.jpg"
src="bowtie.gif"
SRC="FOO.GIF"

我想要的是:

src="hello-world.jpg"
src="bowtie.gif"
src="smiley.gif"
SRC="FOO.GIF"
SRC="BAR.GIF"
SRC="INTERNET-CIRCA-1997.GIF"

如何在每一行中出现所有事件?

3 个答案:

答案 0 :(得分:1)

您需要的是能够在SQL Server中运行“coss apply”功能。创建一个将值分解为结果表的函数,然后在连接条件中使用'cross apply'概念连接该结果表。

执行此操作将导致生成表输出的函数,使用String的输入,它将在字符串上运行“游标”,然后将值添加到结果表中。如果你调用函数“SearchSRC”,它看起来会有点像:

select capply.Sources
from mytable
     cross apply SearchSrc(mytable.PostHTML) as capply

它可能相对复杂,但文档也有一个例子。

我把SQLFiddle demonstrating this solution here放在一起(注意我的SQLFiddle代码的早期版本产生了一个无限循环,现在它有@cnt变量可以用来限制循环。我会建议一个默认的输入参数。

重要的部分是功能:

CREATE FUNCTION SearchSRC(@html AS NVarChar(max))
RETURNS @SRC Table
(
  cnt     int,
  cstart   int,
  cend     int,
  src     NVarChar(250)
)
as
BEGIN

  declare @lcase NVarchar(max),
          @start int,
          @end int,
          @cnt int = 0

  select @lcase = lower(@html)

  select @start = CharIndex('src="', @lcase, 1) + 5
  select @end = charIndex('"', @lcase, @start)

  --insert into @SRC
  --select @cnt, @start, @end, @lcase

  -- use 5 start for start because we add 5 manually
  while @cnt < 10 and @start > 5 and @end > @start
  begin
    select @cnt = @cnt + 1

    insert into @SRC
    select @cnt, @start, @end, SubString(@html, @start, @end - @start)

    select @start = CharIndex('src="', @lcase, @end + 1) + 5
    select @end = CharIndex('"', @lcase, @start)

  end

  return
END

作为查询的一部分调用:

select id, crapp.src
from Posts
     cross apply SearchSRC(PostHTML) as crapp

答案 1 :(得分:0)

试试这个 -

SELECT 'SRC="' + LEFT(RIGHT(PostHTML, LEN(PostHTML) - CHARINDEX('src="', PostHTML) - 4), CHARINDEX('"', RIGHT(PostHTML, LEN(PostHTML) - CHARINDEX('src="', PostHTML) - 4 - 1))) + '"'
FROM post

<强>输出

src="hello-world.jpg"
src="bowtie.gif"
src="smiley.gif"
SRC="FOO.GIF"
SRC="BAR.GIF"
SRC="INTERNET-CIRCA-1997.GIF"

答案 2 :(得分:0)

如果您使用的是2008年及以上版本,那么您可以使用CTE答案:

create table #objids_table ( PostId int, PostHTML nvarchar(max) null )

逐个插入所有值

;with T(PostHTML, starts, pos) as ( select PostHTML, 1, charindex('src', PostHTML) from #objids_table union all select PostHTML, cast(pos + 1 as int), charindex('src', PostHTML, pos + 1) from T where pos > 0 ) select substring(PostHTML, starts -1, charindex('"', PostHTML, starts + 4) - (starts - 2)) as img from T where starts <> 1 order by PostHTML, starts

你可以在这里看一下类似的答案: SQL Server - find nth occurrence in a string