简体   繁体   English

SQL 仅从 VARCHAR 列返回 SELECT 中的特定字符

[英]SQL Return only specific characters in SELECT from VARCHAR column

I am stuck on an issue in SQL Server.我在 SQL Server 中遇到了一个问题。 I have a VARCHAR column called Name in my table:我的表中有一个名为NameVARCHAR列:

在此处输入图像描述

I am trying to get the column to only return valid characters when doing a select on it.我试图让该列在对其进行选择时仅返回有效字符。 For example, I am only accepting any letters [AZ], numbers [0-9] or a question mark [?] but list can change so need to be flexible.例如,我只接受任何字母 [AZ]、数字 [0-9] 或问号 [?],但列表可以更改,因此需要灵活。 The reason why I am only accepting certain characters is due to our supplier specification which I send data to.我只接受某些字符的原因是由于我向其发送数据的供应商规范。 It will break their system if I send then an invalid character.如果我发送一个无效字符,它会破坏他们的系统。

SELECT Name FROM @table

For the purpose of asking the question, I have included a small example below where I insert into a table variable.为了提出这个问题,我在下面包含了一个小例子,我在其中插入了一个表变量。 My question is aimed towards the select part as I am trying to work on data already inserted.我的问题针对选择部分,因为我正在尝试处理已插入的数据。

DECLARE @table AS TABLE
(
    ID INT ,
    Name VARCHAR(500) ,
    Age INT 
)

INSERT INTO @table 
VALUES (1, 'Hello ## World! Test8.?##', 23), 
       (2, 'Need specific characters only Test8.? ]]', 22)

-- Only accept [A-Z][0-9][?]
SELECT Name FROM @table

Please note, the scenario above is a small example and the data is just dummy data I just added to make it easier to ask the question.请注意,上面的场景是一个小例子,数据只是我刚刚添加的虚拟数据,以便更容易提出问题。 The data already exist.数据已经存在。 I have no control over it.我无法控制它。 I only have access to it and need to tidy it up via doing a select.我只能访问它,需要通过选择来整理它。

Expected results with only returning valid characters:仅返回有效字符的预期结果:

在此处输入图像描述

For first row it will return "Hello World Test8?"对于第一行,它将返回“Hello World Test8?” and for second row it will return "Need specific chatacters only Test8?".对于第二行,它将返回“只需要特定的字符 Test8?”。

What I have tried so far is doing a replace on the select to get the result:到目前为止我尝试的是对选择进行替换以获得结果:

-- Only accept [A-Z][0-9][?]
SELECT REPLACE(REPLACE(REPLACE(REPLACE(Name, '#', ''), '!', ''), ']', ''), '.', '') FROM @table

However, this only works if I knew which characters are invalid.但是,这只有在我知道哪些字符无效时才有效。 As mentioned earlier in question, I only know the opposite which are valid characters.如前所述,我只知道相反的字符是有效字符。 A valid character is a letter [AZ] or number [0-9] or a question mark.有效字符是字母 [AZ] 或数字 [0-9] 或问号。 This means I have a massive list of invalid characters I need to add if I went towards a replace solution.这意味着如果我要使用替换解决方案,我需要添加大量无效字符。

Any idea how I can achieve this within the select statement?知道如何在 select 语句中实现这一点吗?

I am on SQL Server Version 2012.我使用的是 SQL Server 2012 版。

There is no built-in functionality for this, though this was implemented by people before:没有内置的功能,虽然这是以前的人实现的:

https://raresql.com/2013/03/11/sql-server-function-to-parse-alphanumeric-characters-from-string/ https://raresql.com/2013/03/11/sql-server-function-to-parse-alphanumeric-characters-from-string/

Using this (all copyrights to the author) would be:使用这个(作者的所有版权)将是:

CREATE FUNCTION dbo.[UDF_Extract_Alphanumeric_From_String]
(
@String VARCHAR(MAX) -- Variable for string
)
RETURNS VARCHAR(MAX)
BEGIN
DECLARE @RETURN_STRING VARCHAR(MAX)
 
; WITH  N1 (n) AS (SELECT 1 UNION ALL SELECT 1),
N2(n) AS (SELECT 1 FROM N1 AS X, N1 AS Y),
N3(n) AS (SELECT 1 FROM N2 AS X, N2 AS Y),
N4(n) AS (SELECT ROW_NUMBER() OVER(ORDER BY X.n)
FROM N3 AS X, N3 AS Y)
 
SELECT @RETURN_STRING=ISNULL(@RETURN_STRING,'')+ SUBSTRING(@String,Nums.n,1)
FROM N4 Nums
WHERE Nums.n <=LEN(@String) AND PATINDEX('%[0-9A-Za-z ]%',SUBSTRING(@String,Nums.n,1)) > 0
 
RETURN @RETURN_STRING
END
 
GO
SELECT dbo.[UDF_Extract_Alphanumeric_From_String] ('Hello ## World! Test8.?##') as [Result]

--OUTPUT

Result
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Hello  World Test8

(1 row affected)


Completion time: 2022-12-20T22:47:24.8872397+01:00

Here's a different approach with a UDF...这是使用 UDF 的另一种方法......

CREATE FUNCTION LeaveValidChars 
(
    @p1 varchar(100)
)
RETURNS varchar(100)
AS
BEGIN
    DECLARE @Result varchar(100)='', @p INT = 0, @c CHAR(1);
    WHILE @p < LEN(@p1)
    BEGIN
        SET @c=substring(@p1, @p, 1)
        IF CHARINDEX(@c,'ABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890?')>0 
            SET @result=@result+@c;
        SET @p=@p+1
    END
    RETURN @Result;
END
GO

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM