T-SQL의 SQL Server 정규식


127

SPSQL Server에 대해 T-SQL (CLR 없음, 확장 , 순수 T-SQL 없음)로 작성된 정규식 라이브러리가 있으며 공유 호스팅과 작동해야합니까?

편집하다:

  • 덕분에, 나는에 대해 알고 PATINDEX, LIKE, xp_ sps및 CLR 솔루션을
  • 나는 또한 그것이 정규 표현식을위한 최고의 장소가 아니라는 것을 알고 있습니다. 질문은 이론적입니다 :)
  • 기능 감소도 허용됩니다

2
나도이 질문이 있습니다. 데이터베이스가 이것이 가장 좋은 장소는 아니지만 실제로 다른 솔루션에는 서버를 재구성하기 위해 SQL 관리자 권한이 필요하다는 것을 알고 있습니다. 불행히도 일부 고객은 CLR 등을 사용하도록 선택하지 않으며 데이터베이스 전용 솔루션을 고수합니다.
Paul Draper

@PaulDraper와 xnagyg : 왜 SQLCLR을 배제합니까? 쿼리에서 정규식을 가져 오는 가장 적절한 방법입니다. 그리고 일부 고객이 CLR을 사용하지 않기로 선택한 이유는 무엇입니까? 나는 아직 타당한 이유 를 발견하지 못했습니다 . 물론 "보안"과 "성능"은 들리지만, SQLCLR의 작동 방식과 제한 방법을 이해하지 못한 결과가 될 수 있습니다.
Solomon Rutzky 2016 년

3
@srutzky : 대부분의 공유 호스팅 공급자는 CLR을 허용하지 않습니다. "보안"과 "성능"에 대해 질문해야합니다.
xnagyg

@xnagyg 물론, 몇 가지를 물어볼 수 있습니다. 그러나 그룹의 행동을 가리키는 것은 그 행동에 대한 " 유효한 이유가 있습니까" 라는 질문을 어떤 식 으로든 다루지 않습니다 . 공유 호스팅 제공 업체가 모두 동일한 오해를 바탕으로 정책을 설정하는 것도 쉬울 수 있습니다. 그리고 다른 것이 없다면, 그들 모두 가 SQLCLR을 허용하지 않는다는 단순한 사실은 실제로 문제가 있다는 생각보다 문제 가 없다는 생각을 실제로 지원합니다. 그 문제는 허용하지 않습니다.
Solomon Rutzky 2016 년

@xnagyg 또한, 또는 SAFE표시되지 않은 어셈블리 EXTERNAL_ACCESS또는 표시되지 않은 어셈블리 측면에서 말하고 있음을 분명히해야합니다 UNSAFE. 공유 환경 인 Microsoft Azure SQL Database V12 (예 : 2014 년 말 현재 새 버전)는 어셈블리를 표시 할 수 있으며 DLL을 업로드 할 수 없으므로 DLL 대신 SAFE로드됩니다 FROM 0x.... 그러나 SAFE다른 매우 유용한 함수의 정규 표현식 및 LOTS에 필요한 전부입니다.
Solomon Rutzky 2016 년

답변:


77

방법에 대한 PATINDEX의 기능?

TSQL의 패턴 일치는 완전한 정규식 라이브러리는 아니지만 기본 사항을 제공합니다.

(온라인 서적에서)

Wildcard  Meaning  
% Any string of zero or more characters.

_ Any single character.

[ ] Any single character within the specified range 
    (for example, [a-f]) or set (for example, [abcdef]).

[^] Any single character not within the specified range 
    (for example, [^a - f]) or set (for example, [^abcdef]).

7
적어도 10 년 동안 (SQL Server 2005+) LIKE모든 기능을 지원했습니다 PATINDEX. 그 전에 몰라요 ...
TJ Crowder

1
그러나 이것은 가변 개수의 ASCII 문자와 일치하는 패턴을 지정하도록 허용하지 않습니다. %0 개 이상의 문자 (상관없이)와 [...]일치하고 하나만 일치하며 그 사이에는 아무 것도 없습니다.
Martijn Pieters

LIKE는 PATINDEX> 0과 동일합니다
리버스 엔지니어

21

CLR과 함께 정규식을 사용하는 데 관심이 있다면 여기에 해결책이 있습니다. 아래 함수 (C # .net 4.5)는 패턴이 일치하면 1을, 패턴이 일치하지 않으면 0을 반환합니다. 하위 쿼리에서 행에 태그를 지정하는 데 사용합니다. SQLfunction 속성은이 방법이 SQL 서버가 사용할 실제 UDF임을 SQL 서버에 알려줍니다. 파일을 management studio에서 액세스 할 수있는 장소에 dll로 저장하십시오.

// default using statements above
using System.Data.SqlClient;
using System.Data.SqlTypes;
using Microsoft.SqlServer.Server;
using System.Text.RegularExpressions;

namespace CLR_Functions
{   
    public class myFunctions
    {
        [SqlFunction]
        public static SqlInt16 RegexContain(SqlString text, SqlString pattern)
        {            
            SqlInt16 returnVal = 0;
            try
            {
                string myText = text.ToString();
                string myPattern = pattern.ToString();
                MatchCollection mc = Regex.Matches(myText, myPattern);
                if (mc.Count > 0)
                {
                    returnVal = 1;
                }
            }
            catch
            {
                returnVal = 0;
            }

            return returnVal;
        }
    }
}

Management Studio에서 프로그래밍 기능-어셈블리-새 어셈블리를 통해 dll 파일 가져 오기

그런 다음이 쿼리를 실행하십시오.

CREATE FUNCTION RegexContain(@text NVARCHAR(50), @pattern NVARCHAR(50))
RETURNS smallint 
AS
EXTERNAL NAME CLR_Functions.[CLR_Functions.myFunctions].RegexContain

그런 다음 어셈블리를 저장 한 데이터베이스를 통해 기능에 완전히 액세스 할 수 있어야합니다.

그런 다음 쿼리에서 사용하십시오.

SELECT * 
FROM 
(
    SELECT
        DailyLog.Date,
        DailyLog.Researcher,
        DailyLog.team,
        DailyLog.field,
        DailyLog.EntityID,
        DailyLog.[From],
        DailyLog.[To],
        dbo.RegexContain(Researcher, '[\p{L}\s]+') as 'is null values'
    FROM [DailyOps].[dbo].[DailyLog]
) AS a
WHERE a.[is null values] = 0

14

LIKE를 사용하여 사용할 수있는 몇 가지 기본 패턴 일치가 있습니다. 여기서 %는 숫자 및 문자 조합과 일치하고 _는 하나의 문자와 일치하며 [abc]는 a, b 또는 c와 일치 할 수 있습니다. MSDN 사이트 에 대한 추가 정보가 있습니다. .


5

SQL Server 2016 이상을 사용 sp_execute_external_script하는 경우 R과 함께 사용할 수 있습니다 . grep및과 같은 정규식 검색 기능이 있습니다 grepl.

다음은 이메일 주소의 예입니다. SQL Server 데이터베이스 엔진을 통해 일부 "사람"을 쿼리하고 해당 사용자에 대한 데이터를 R에게 전달하고 R이 잘못된 전자 메일 주소를 가진 사용자를 결정하게하고 R이 해당 하위 집합을 SQL Server로 다시 전달하도록합니다. "사람"은 샘플 데이터베이스 의 [Application].[People]테이블에 [WideWorldImporters]있습니다. 이들은라는 데이터 프레임으로 R 엔진에 전달됩니다 InputDataSet. R은 "not"연산자 (느낌표!)와 함께 grepl 기능을 사용하여 RegEx 문자열 검색 패턴과 일치하지 않는 전자 메일 주소를 가진 사람을 찾습니다.

EXEC sp_execute_external_script 
 @language = N'R',
 @script = N' RegexWithR <- InputDataSet;
OutputDataSet <- RegexWithR[!grepl("([_a-z0-9-]+(\\.[_a-z0-9-]+)*@[a-z0-9-]+(\\.[a-z0-9-]+)*(\\.[a-z]{2,4}))", RegexWithR$EmailAddress), ];',
 @input_data_1 = N'SELECT PersonID, FullName, EmailAddress FROM Application.People'
 WITH RESULT SETS (([PersonID] INT, [FullName] NVARCHAR(50), [EmailAddress] NVARCHAR(256)))

SQL Server 호스트에 적절한 기능이 설치되어 있어야합니다. SQL Server 2016의 경우 "SQL Server R 서비스"라고합니다. SQL Server 2017의 경우 이름이 "SQL Server Machine Learning Services"로 바뀌 었습니다.

결산 사고 Microsoft의 SQL (T-SQL) 구현은 RegEx를 기본적으로 지원하지 않습니다. 이 제안 된 솔루션은 CLR 저장 프로 시저를 사용하는 것보다 OP에 더 이상 바람직하지 않을 수 있습니다. 그러나 문제에 접근하는 추가 방법을 제공합니다.


4

다른 사람이 여전히이 질문을보고있는 경우 http://www.sqlsharp.com/정규식 CLR 함수 를 데이터베이스 에 추가 할 수 있는 무료 방법 입니다.


3
다시 한번, 저는 OP가 요구 한 것이 아니라 CLR 솔루션입니다
리버스 엔지니어

10
@DaveBoltman : 그는 2008 년에 질문을했습니다. 사람들은 때때로 이것을 검색하고 CLR을 피하고 싶지 않고이 질문을 가로 질러 실행합니다. 이것은 나를 도왔고 그들을 도울 수 있습니다.
존 피셔

물론, 내가 할 @JohnFisher 당신과 동의 - 그것은 이다 CLR을 사용하여 누군가를위한 도움이 대답. 그러나 2015 년에도 OP는 2008 년과 마찬가지로 여러 가지 이유로 SQL 프로젝트 (CLR 없음)에서 SQL 전용 솔루션을 여전히 원했습니다. 연도는 중요하지 않습니다. 예를 들어 자동차 배터리 는 1859 . 그러나 100 년 이상 후에 출시 된 NiMH 배터리와 같은 최신 배터리를 사용하는 것을 피하고 싶을 것입니다. 여러 가지 이유로 (자동차를 전혀 구입할 수없는 등)
리버스 엔지니어

2
@DaveBoltman : 당신은 "사람들이 때때로 이것을 찾고 CLR을 피하고 싶지 않고이 질문을 가로 질러 실행하는"부분을 놓쳤다. 핵심 포인트였습니다.
John Fisher

확실합니다-당신은 @ JohnFisher 맞습니다. 도움이되어
기쁘고

2

OLE 자동화를 사용하여 VBScript 정규식 기능을 사용할 수 있습니다. 이것은 어셈블리를 만들고 유지 관리하는 오버 헤드보다 훨씬 낫습니다. 더 나은 수정 버전의 기본 버전을 얻으려면 댓글 섹션을 확인하십시오.

http://blogs.msdn.com/b/khen1234/archive/2005/05/11/416392.aspx

DECLARE @obj INT, @res INT, @match BIT;
DECLARE @pattern varchar(255) = '<your regex pattern goes here>';
DECLARE @matchstring varchar(8000) = '<string to search goes here>';
SET @match = 0;

-- Create a VB script component object
EXEC @res = sp_OACreate 'VBScript.RegExp', @obj OUT;

-- Apply/set the pattern to the RegEx object
EXEC @res = sp_OASetProperty @obj, 'Pattern', @pattern;

-- Set any other settings/properties here
EXEC @res = sp_OASetProperty @obj, 'IgnoreCase', 1;

-- Call the method 'Test' to find a match
EXEC @res = sp_OAMethod @obj, 'Test', @match OUT, @matchstring;

-- Don't forget to clean-up
EXEC @res = sp_OADestroy @obj;

당신이 얻을 경우 SQL Server blocked access to procedure 'sys.sp_OACreate'...오류를 사용할 sp_reconfigure수 있도록 Ole Automation Procedures. (예, 불행히도 서버 수준 변경입니다!)

Test방법 에 대한 자세한 내용은 여기를 참조하십시오

행복한 코딩


sry, 나는 이것이 오래되었다는 것을 알고 있지만, 왜 OLE를 통한 VBScript가 CLR보다 "좋은 방법"입니까? 유지 관리 만 생각한다면 옳을 수 있지만 성능은 어떻습니까?
Swe

1
@swe '더 나은 방법'으로, 나는이 목적을 위해 .NET 어셈블리를 만들고 유지 관리하는 오버 헤드로 인해 절약 된 시간을 말합니다.
James Poulose
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.