如何使用T-SQL删除未知字符?

时间:2017-07-24 07:25:35

标签: sql-server tsql sql-server-2016

我尝试使用脚本来消除字符串中的中文字符以及要删除的中文字符。请参阅下面的示例。谢谢。

select LTRIM(SUBSTRING('Tower 6A 第6A座', PATINDEX('%[a-zA-Z0-9]%', 'Tower 6A 第6A座'), LEN('Tower 6A 第6A座')))
select LTRIM(REPLACE(SUBSTRING('Tower 6A 第6A座', CHARINDEX(N'樓', 'Tower 6A 第6A座') + 1, LEN('Tower 6A 第6A座')), ' ', ''))

示例字符串:

Tower 6A 第6A座
Tower 3 第3座

结果不好:

Tower 6A ?6A?
Tower6A?6A?
Tower 3 ?3?
Tower3?3?

好结果,我想实现:

Tower 6A
Tower 6A
Tower 3
Tower 3

5 个答案:

答案 0 :(得分:3)

试试这个

   SELECT Replace(Replace('Tower 6A 第6A座','[^a-zA-Z0-9]+', ''),'?','')

答案 1 :(得分:2)

看起来很奇怪,但做的工作。但是,我不会指望出色的表现:

;WITH string AS (
    SELECT N'Tower 6A 第6A座' s
),
split AS (
    select LEFT(s, 1) s_item,
       STUFF(s, 1, 1, N'') s
    from string
    union all
    select LEFT(s, 1),
       STUFF(s, 1, 1, N'')
    from split
    where s > ''
)
,
remove_non_ascii AS ( 
    SELECT s_item, UNICODE(s_item) s_unicode
    FROM split WHERE UNICODE(s_item)<256
)
SELECT STUFF((SELECT s_item FROM remove_non_ascii
FOR XML PATH, TYPE).value('.[1]', 'NVARCHAR(MAX)'), 1,0, '');

它的作用:

  1. 将字符串拆分为行

  2. 消除大于256的UNICODE字符(你可以摆弄条件)

  3. 将字符串放在一起

  4. 它使用递归查询,因此在字符串长度超过100个字符的情况下,您需要通过添加:OPTION (MAXRECURSION n)来扩展递归循环的数量(其中n是新的递归循环量)

答案 2 :(得分:0)

试试这个

;With cte(Data)
AS
(
SELECT 'Tower 6A 第6A座' UNION ALL
SELECT 'Tower 3 第3座'
)
SELECT
CASE WHEN CHARINDEX('Tower', DATA)= 0 THEN 'Tower ' + DATA ELSE DATA END AS DATA
FROM
(
SELECT
Split.a.value('.', 'VARCHAR(1000)') AS Data
FROM
(
SELECT  CAST('<S>' + REPLACE(REPLACE(Data, '?', '</S><S>'),'','</S><S>') + '</S>' AS XML) AS Data
FROM cte
) AS 
    A CROSS APPLY Data.nodes('/S') AS Split(a)
) DT
Where
DT.Data <> ''

结果

DATA
----------
Tower 6A 
Tower 6A
Tower 3 
Tower 3

答案 3 :(得分:0)

使用delimitedSplit8k可以执行此操作:

-- Sample data
DECLARE @table TABLE (someid int identity, string nvarchar(100));
INSERT @table VALUES (N'Tower 6A 第6A座'), (N'Tower 3 第3座');

-- Solution
WITH base AS
(
  SELECT someid, ItemNumber, itemClean = replace(item,'?','')
  FROM @table t
  CROSS APPLY dbo.delimitedSplit8K(t.string, ' ')
)
SELECT someid, newstring = b1.itemClean + ' ' +  b2.itemClean
FROM base b1
CROSS APPLY 
(
  SELECT itemClean 
  FROM base b2 WHERE ItemNumber = 1 AND b1.someid = b2.someid
) b2
WHERE b1.ItemNumber > 1;

结果:

someid      newstring
----------- ---------
1           6A Tower
1           6A Tower
2           3 Tower
2           3 Tower

答案 4 :(得分:0)

解决此问题的一种方法是利用SQL Server 2016执行R脚本的能力。要使此方法起作用,您必须确保已在SQL Server上安装R服务,您还必须启用“sp_execute_external_script”存储过程。 启用外部脚本如下:

IF NOT EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[ExampleData]') AND type in (N'U'))
BEGIN

    CREATE TABLE [dbo].[ExampleData](
        [RawData] [nvarchar](100) NULL
    ) ON [PRIMARY]

    INSERT INTO ExampleData
    (
        [RawData]
    )
    VALUES ( N'Tower 6A 第6A座');

    INSERT INTO ExampleData
    (
        [RawData]
    )
    VALUES ( N'Tower 3 第3座');

END

DECLARE @inputQuery NVARCHAR(MAX) = N'SELECT CAST([RawData] AS VARCHAR(100)) as a FROM ExampleData'

DECLARE @RScript NVARCHAR(MAX) = N'
pattern <-"\\?.*\\?";
inData$a <- sub(pattern, "\\1", inData$a, perl = T );
outData <- inData;';


EXEC sp_execute_external_script @language = N'R'
, @script = @RScript
, @input_data_1 = @inputQuery
, @input_data_1_name = N'inData'
, @output_data_1_name=N'outData'
with result sets ( (a varchar(300)));

还要确保“SQL Server Launchpad”服务正在运行。您可能还必须重新启动SQL Server。

如果我们将包含中文字符的输入数据从Unicode转换为ASCII(VARCHAR),那么SQL Server会自动将中文字符转换为问号“?”。 接下来,我们可以使用R语言模式匹配功能删除问号之间的所有文本(正式是我们的中文字符),如下例所示:

a