从SQL

时间:2016-03-16 10:10:06

标签: sql sql-server regex

我在BOOKNAME表中有列名BOOKS,除了字母数字之外,它还可以包含许多特殊字符,例如',$#()[],

如何编写查询以仅显示所有行中的特殊字符并将其合并,例如

Row number Book name   
1           Alice$inWonder(Land)
2           Tom Harry#$%^& adventures

因此查询应显示类似$()#%^&

的输出

我试过这个,但看不出为什么它只显示这些字符

SELECT replace(BOOKNAME , '%[^a-zA-Z0-9 ]%', '') FROM BOOKS 
WHERE BOOKNAME like '%[^a-zA-Z0-9 ]%'

3 个答案:

答案 0 :(得分:1)

为方便起见,您可以创建用户定义的函数来选择特殊字符,如下所示:

用户定义的功能:[dbo]。[SpecialCharacters]

create Function [dbo].[SpecialCharacters](@res VarChar(1000))
returns varchar(1000)
as
begin

declare @str as varchar(50)
set @str = '%[a-z]%'
while patindex(@str, @res) > 0
set @res = stuff(@res, patindex(@str, @res), 1, '')

return @res
End 

然后,

select '' + stuff((select t.specialchars as specialchars from (
    select replace(dbo.[SpecialCharacters](bookname), ' ', '') as specialchars           
    from books
)t
for xml path, type).value('.[1]', 'nvarchar(max)'), 1, 0, '');

<强>结果

+--------------+
| specialchars |
+--------------+
| $()#$%^&     |
+--------------+

答案 1 :(得分:1)

您可以使用while loop.

来完成此操作
SET NOCOUNT ON
DECLARE @loop INT
DECLARE @str VARCHAR(8000), @output VARCHAR(8000)
SELECT @str = 'ab123ce23,4f$e', @output=''
SET @loop = 1
WHILE @loop < LEN(@str)
BEGIN
SET @output=@output+CASE WHEN ASCII(SUBSTRING(@str,@loop,1)) BETWEEN 48 AND 57 THEN SUBSTRING(@str,@loop,1) ELSE '' END
SET @loop = @loop + 1
END
SELECT @output
礼貌:pinal dave,http://blog.sqlauthority.com

请找到以下相同的链接

http://blog.sqlauthority.com/2015/08/29/sql-server-remove-all-characters-from-a-string-using-t-sql/

答案 2 :(得分:0)

我建议建立regexp-match + regexp-replace CLR函数,但你也可以尝试这种老式的方法:

;with list as
(
  select 'Alice#wndlnd' as name
  union all
  select 'asdf?!@zz'
  union all
  select 'Regular'
  union all
  select 'last$'
),
list_cleared as
(
  select 
    replace(
      replace(
        replace(
          replace(
            replace(
              replace(
                replace(
                  replace(
                    replace(
                      replace(
                        replace(
                          replace(
                            replace(
                              replace(
                                replace(
                                  replace(
                                    replace(
                                      replace(
                                        replace(
                                          replace(
                                            replace(
                                              replace(
                                                replace(
                                                  replace(
                                                    replace(
                                                      replace(name
                                                        , 'a', '')
                                                      , 'b', '')
                                                    ,'c', '')
                                                  , 'd', '')
                                                , 'e', '')
                                              ,'f', '')
                                            , 'g', '')
                                          , 'h', '')
                                        ,'i', '')
                                      , 'j', '')
                                    , 'k', '')
                                  ,'l', '')
                                ,'m', '')
                              , 'n', '')
                            , 'o', '')
                          ,'p', '')
                        , 'q', '')
                      , 'r', '')
                    ,'s', '')
                  ,'t', '')
                , 'u', '')
              , 'v', '')
            ,'w', '')
          , 'x', '')
        , 'y', '')
      ,'z', '') as spec_chars
  from list
)
select 
  (
    select l.spec_chars
    from list_cleared l
    where l.spec_chars <> ''
    for xml path(''), type
  ).value('.', 'varchar(max)') as spec_chars