使用T-SQL进行复杂的搜索/过滤文本列

时间:2013-04-25 00:47:14

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

我在我的环境中使用SQL Server 2005.

我有一个列,每行包含一些关于某些SQL查询的数据。每行看起来像数据库中的一个长行,但是当您从行中提取数据时,它会被拆分为多行,因为它包含回车符。

以下是来自回车分割的列的一行的数据示例。我试图找出一种方法,到目前为止还没有成功,我可以提取包含“伪=”的每一行上等号后面的所有内容,除了前导和尾随空格。

所以在包含“pseudo =”的行上,我想要在=符号后面的所有内容。然后我想修剪前导和尾随空格,如果有的话。我还想在每个“伪=”行的末尾维护回车。然后,我想将所有“伪=”行的新字符串存储到新列中的新行中。

我的SQL不是很强大,这个小小的谜题让我陷入了困境。任何帮助是极大的赞赏。请注意,该列最多只有500到600行,但如果有任何问题,那么其中有一堆文本。

0x8A40D34D4BEC294D8934029D569B2BFE
table=ca_discovered_hardware
target_type=1
label=label
typefield=
primarykeyfield=dis_hw_uuid
secondarykeyfield=domain_uuid
excludeclause=
[Arguments]
Arguments=12
[Argument 1]
type=1
pseudo= ( 
sql=(
valid=1
[Argument 2]
type=11
pseudo=(Link Query '[ES] IPQ: Tokyo (JPN)' using 'default' method)
sql=dis_hw_uuid in ($TARGETLINKSQL$)
valid=1
queryuuid=f8e488a2b34ee24b85db3f8fafd4e9a2
query_name=[ES] IPQ: S&B - Tokyo (JPN)
[Argument 3]
type=1
pseudo= ) 
sql=)
valid=1
[Argument 4]
type=1
pseudo= AND 
sql= AND 
valid=1
[Argument 5]
type=1
pseudo= NOT 
sql= NOT 
valid=1
[Argument 6]
type=1
pseudo= ( 
sql=(
valid=1
[Argument 7]
type=9
pseudo=(Current Server = 'APTOPRK01CIGE')
sql=ca_discovered_hardware.dis_hw_uuid in (SELECT object_uuid FROM ca_agent WHERE server_uuid IN (SELECT server_uuid FROM ca_server WHERE label='APTOPRK01CIGE'))
valid=1
[Argument 8]
type=1
pseudo= OR 
sql= OR 
valid=1
[Argument 9]
type=11
pseudo=(Link Query '[DM] EXQ: Obsolete Exclude' using 'default' method)
sql=dis_hw_uuid in ($TARGETLINKSQL$)
valid=1
queryuuid=00000000000000000000000000000000
query_name=[DM] EXQ: Obsolete Exclude
[Argument 10]
type=1
pseudo= OR 
sql= OR 
valid=1
[Argument 11]
type=11
pseudo=(Link Query '[DM] EXQ: Server Exclude' using 'default' method)
sql=dis_hw_uuid in ($TARGETLINKSQL$)
valid=1
queryuuid=00000000000000000000000000000000
query_name=[DM] EXQ: Server Exclude
[Argument 12]
type=1
pseudo= ) 
sql=)
valid=1

1 个答案:

答案 0 :(得分:1)

试试这段代码。

用户定义的函数iter_charlist_to_tbl将字符串拆分为具有已定义的分隔符的行。 (取自here

my_convert函数将字符串行连接到字符串

SQL Fiddle

MS SQL Server 2008架构设置

create table t ( str varchar(max))
go

create function my_convert(@str varchar(max))
returns varchar(max)
as
begin
  declare @p_str varchar(max), @result varchar(max), @delim varchar(2)
  set @delim = char(10)
  set @result = ''

  declare CUR cursor for 
    select right(str, len(str) -7) as result--, str 
    from dbo.iter_charlist_to_tbl(@str, @delim) t
    where str like 'pseudo=%'
  open CUR
  fetch next from CUR into @p_str
  while @@fetch_status = 0
  begin
    set @result = @result + @p_str + char(10)
    fetch next from CUR into @p_str
  end
  close CUR
  deallocate CUR
  return @result
end
go


CREATE FUNCTION iter_charlist_to_tbl
                 (@list      nvarchar(MAX),
                  @delimiter nvarchar(2) = N',')
      RETURNS @tbl TABLE (listpos int IDENTITY(1, 1) NOT NULL,
                          str     varchar(4000)      NOT NULL,
                          nstr    nvarchar(2000)     NOT NULL) AS

BEGIN
   DECLARE @endpos   int,
           @startpos int,
           @textpos  int,
           @chunklen smallint,
           @tmpstr   nvarchar(4000),
           @leftover nvarchar(4000),
           @tmpval   nvarchar(4000)

   SET @textpos = 1
   SET @leftover = ''
   WHILE @textpos <= datalength(@list) / 2
   BEGIN
      SET @chunklen = 4000 - datalength(@leftover) / 2
      SET @tmpstr = @leftover + substring(@list, @textpos, @chunklen)
      SET @textpos = @textpos + @chunklen

      SET @startpos = 0
      SET @endpos = charindex(@delimiter COLLATE Slovenian_BIN2, @tmpstr)

      WHILE @endpos > 0
      BEGIN
         SET @tmpval = ltrim(rtrim(substring(@tmpstr, @startpos + 1,
                                             @endpos - @startpos - 1)))
         INSERT @tbl (str, nstr) VALUES(@tmpval, @tmpval)
         SET @startpos = @endpos
         SET @endpos = charindex(@delimiter COLLATE Slovenian_BIN2,
                                 @tmpstr, @startpos + 1)
      END

      SET @leftover = right(@tmpstr, datalength(@tmpstr) / 2 - @startpos)
   END

   INSERT @tbl(str, nstr) VALUES (ltrim(rtrim(@leftover)), ltrim(rtrim(@leftover)))
   RETURN
END
go

insert t (str) values (
  '0x8A40D34D4BEC294D8934029D569B2BFE
table=ca_discovered_hardware
target_type=1
label=label
typefield=
primarykeyfield=dis_hw_uuid
secondarykeyfield=domain_uuid
excludeclause=
[Arguments]
Arguments=12
[Argument 1]
type=1
pseudo= ( 
sql=(
valid=1
[Argument 2]
type=11
pseudo=(Link Query ''[ES] IPQ: Tokyo (JPN)'' using ''default'' method)
sql=dis_hw_uuid in ($TARGETLINKSQL$)
valid=1
queryuuid=f8e488a2b34ee24b85db3f8fafd4e9a2
query_name=[ES] IPQ: S&B - Tokyo (JPN)
[Argument 3]
type=1
pseudo= ) 
sql=)
valid=1
[Argument 4]
type=1
pseudo= AND 
sql= AND 
valid=1
[Argument 5]
type=1
pseudo= NOT 
sql= NOT 
valid=1
[Argument 6]
type=1
pseudo= ( 
sql=(
valid=1
[Argument 7]
type=9
pseudo=(Current Server = ''APTOPRK01CIGE'')
sql=ca_discovered_hardware.dis_hw_uuid in (SELECT object_uuid FROM ca_agent WHERE server_uuid IN (SELECT server_uuid FROM ca_server WHERE label=''APTOPRK01CIGE''))
valid=1
[Argument 8]
type=1
pseudo= OR 
sql= OR 
valid=1
[Argument 9]
type=11
pseudo=(Link Query ''[DM] EXQ: Obsolete Exclude'' using ''default'' method)
sql=dis_hw_uuid in ($TARGETLINKSQL$)
valid=1
queryuuid=00000000000000000000000000000000
query_name=[DM] EXQ: Obsolete Exclude
[Argument 10]
type=1
pseudo= OR 
sql= OR 
valid=1
[Argument 11]
type=11
pseudo=(Link Query ''[DM] EXQ: Server Exclude'' using ''default'' method)
sql=dis_hw_uuid in ($TARGETLINKSQL$)
valid=1
queryuuid=00000000000000000000000000000000
query_name=[DM] EXQ: Server Exclude
[Argument 12]
type=1
pseudo= ) 
sql=)
valid=1
  ')

查询1

-- table result
declare @long varchar(max)
declare @crlf varchar(2) = char(10)
select @long = str from t
select right(str, len(str) -7) as result--, str 
from dbo.iter_charlist_to_tbl(@long, @crlf) t
where str like 'pseudo=%'

/*--string result
select dbo.my_convert(str) from t
*/

<强> Results

|                                                           RESULT |
--------------------------------------------------------------------
|                                                                ( |
|      (Link Query '[ES] IPQ: Tokyo (JPN)' using 'default' method) |
|                                                                ) |
|                                                              AND |
|                                                              NOT |
|                                                                ( |
|                               (Current Server = 'APTOPRK01CIGE') |
|                                                               OR |
| (Link Query '[DM] EXQ: Obsolete Exclude' using 'default' method) |
|                                                               OR |
|   (Link Query '[DM] EXQ: Server Exclude' using 'default' method) |
|                                                                ) |