T-SQLのSQL Server正規表現


127

SPSQL Server用のT-SQL(CLRなし、拡張された、純粋なT-SQLなし)で記述された正規表現ライブラリはありますか?それは共有ホスティングで動作するはずですか?

編集:

  • おかげで、私が知っているPATINDEXLIKExp_ spsおよびCLRソリューション
  • また、正規表現に最適な場所ではないことも知っています。問題は理論的なものです:)
  • 機能制限も受け入れられます

2
私にもこの質問があります。データベースがこれを配置するのに最適な場所ではないことは知っていますが、実際には、他のソリューションではサーバーを再構成するためにSQL管理者権限が必要です。残念ながら、一部のクライアントはCLRなどを有効にすることを選択せず​​、データベースのみのソリューションに固執しています。
Paul Draper

@PaulDraperとxnagyg:SQLCLRを除外する理由 これは、クエリで正規表現を取得する最も適切な方法です。また、クライアントの一部がCLRを有効にしないことを選択するのはなぜですか。私はまだ正当な理由に出くわしていません。確かに、「セキュリティ」と「パフォーマンス」は聞こえますが、SQLCLRがどのように機能し、どのように制限できるかを理解していないために発生した、偽の理由です。
ソロモンRutzky

3
@srutzky:ほとんどの共有ホスティングプロバイダーはCLRを許可しません。「セキュリティ」と「パフォーマンス」について尋ねる必要があります。)
xnagyg

@xnagyg確かに、いくつか質問できます。ただし、グループの動作を指しても、その動作の「正当な理由はあるか」という質問には決して対応しません。これらの共有ホスティングプロバイダーのすべてが、同じ誤解に基づいてポリシーを設定することも同じくらい簡単です。そして、他に何もない場合、それらすべてがSQLCLRを許可しないという単純な事実は、問題が存在するという考えよりも、問題がないという考えを実際にサポートします。それらの問題とそれを許可するのをやめるでしょう。
ソロモンRutzky

@xnagygまた、私はSAFEどちらかとしてマークされている、EXTERNAL_ACCESSまたはマークされていないアセンブリに関して話していることを明確にする必要がありますUNSAFE(これら2つの後者のアクセス許可セットが共有ホスティング環境で問題になる理由を理解しているため)。共有環境であるMicrosoft Azure SQL Database V12(つまり2014年後半の新しいバージョン)では、アセンブリとしてマークされていますSAFEFROM 0x...DLLをアップロードできないため、DLLの代わりにを介してロードされます)。しかしSAFE、正規表現と他の非常に便利な関数の多くに必要なのはこれだけです。
ソロモンRutzky

回答:


77

PATINDEX関数についてはどうですか?

TSQLのパターンマッチングは完全な正規表現ライブラリではありませんが、基本的な機能を提供します。

(Books Onlineから)

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クラウダー2015

1
しかし、これでは、たとえば可変長のASCII文字に一致するパターンを指定できません。%0個以上の文字に関係なく(関係なく)、[...]1つだけに一致し、間には何もありません。
Martijn Pieters

LIKEはPATINDEX> 0と同じである
逆にエンジニア

21

誰かがCLRで正規表現を使用することに興味がある場合は、ここに解決策があります。以下の関数(C#.net 4.5)は、パターンが一致する場合は1を返し、パターンが一致しない場合は0を返します。サブクエリの行にタグを付けるために使用します。SQLfunction属性は、このメソッドがSQLサーバーが使用する実際のUDFであることをSQLサーバーに通知します。ファイルをdllとして、Management Studioからアクセスできる場所に保存します。

// 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を使用することで利用できる基本的なパターンマッチングがいくつかあります。%は任意の数と文字の組み合わせに一致し、_は任意の1文字に一致し、[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 Services」と呼ばれます。SQL Server 2017では、「SQL Server Machine Learning Services」に名前が変更されました。

締めくくり マイクロソフトのSQL(T-SQL)の実装は、RegExをネイティブでサポートしていません。この提案された解決策は、CLRストアドプロシージャの使用よりもOPにとって望ましいことではありません。しかし、それは問題に取り組むための追加の方法を提供します。


4

他の誰かがまだこの質問を検討している場合は、http://www.sqlsharp.com/を使用すると、正規表現のCLR関数をデータベースに簡単に無料で追加できます。


3
OPはを求めていないものを-もう一度、CLRソリューションi'ts
逆にエンジニア

10
@DaveBoltman:彼は2008年に質問をしました。人々は時々これを検索し、CLRを避けたくないでこの質問に出くわします。これは私を助け、彼らを助けるかもしれません。
John Fisher、

もちろん、@ JohnFisherに同意します。これ、CLRを使用しているユーザーにとって役立つ回答です。しかし、2015年には、さまざまな理由から、SQLプロジェクト(CLRなし)でSQLのみのソリューションが必要です。これは、OPが2008年に行ったのと同じです。年は重要ではありません。例:車のバッテリーは、 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メソッドの詳細については、こちらをご覧ください

ハッピーコーディング


申し訳ありませんが、これは古いのですが、OLE経由のVBScriptがCLRよりも "優れている"のはなぜですか。メンテナンスについてのみ考える場合、あなたは正しいかもしれませんが、パフォーマンスについてはどうですか?
swe

1
@swe「より良い方法」とは、この目的のためだけに.NETアセンブリを作成および保守するオーバーヘッドのために節約された時間を指していました。
James Poulose 16
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.