this one's a bit difficult to explain, especially for a non-native english speaker:
I want to use some elliptic-curve-based digital signature functions of the C# implementation of the BouncyCastle crypto library. I wrote a small C# wrapper class that has the following methods:
public static void generateKeyPair(out byte[] private_key, out byte[] public_key)
public static void SignData(byte[] data, byte[] private_key, out byte[] signature)
public static void VerifyData(byte[] signature, byte[] data, byte[] public_key, out bool ok)
which all access the actual BouncyCastle library, BouncyCastle.Crypto.dll. Then I
created a "Visual Studio Strong Name Key File" and compiled the wrapper class file with the original BouncyCastle DLL as resource and the just created keyfile.
In SQL Server I did the following:
USE ACS
EXEC sp_configure 'show advanced options', 1;
RECONFIGURE WITH OVERRIDE;
EXEC sp_configure 'xp_cmdshell', 1
EXEC sp_configure 'CLR enabled', 1;
RECONFIGURE WITH OVERRIDE;
ALTER DATABASE ACS SET TRUSTWORTHY OFF
USE master
CREATE ASYMMETRIC KEY CLR_Key_Wrapper FROM EXECUTABLE FILE = 'C:\Wrapper.dll'
CREATE ASYMMETRIC KEY CLR_Key_BouncyCastle FROM EXECUTABLE FILE = 'C:\BouncyCastle.Crypto.dll'
CREATE LOGIN CLR_Login_Wrapper FROM ASYMMETRIC KEY CLR_Key_Wrapper
CREATE LOGIN CLR_Login_BouncyCastle FROM ASYMMETRIC KEY CLR_Key_BouncyCastle
GRANT UNSAFE ASSEMBLY TO CLR_Login_Wrapper
GRANT UNSAFE ASSEMBLY TO CLR_Login_BouncyCastle
USE ACS
CREATE ASSEMBLY CLR FROM 'C:\Wrapper.dll' WITH PERMISSION_SET = UNSAFE
GO
CREATE PROCEDURE Generate_Keypair
(
#BSI_or_NIST BIT,
#Private_Key VARBINARY(64) OUTPUT,
#Public_Key VARBINARY(128) OUTPUT
)
AS EXTERNAL NAME CLR.Wrapper.generateKeyPair
GO
CREATE PROCEDURE Sign_Data
(
#BSI_or_NIST BIT,
#Data VARBINARY(8000),
#Private_Key VARBINARY(64),
#Signature VARBINARY(128) OUTPUT
)
AS EXTERNAL NAME CLR.Wrapper.SignData
GO
CREATE PROCEDURE Verify_Data
(
#BSI_or_NIST BIT,
#Signature VARBINARY(128),
#Data VARBINARY(8000),
#Public_Key VARBINARY(128),
#OK BIT OUTPUT
)
AS EXTERNAL NAME CLR.Wrapper.VerifyData
Now, using the three procedures Generate_Keypair, Sign_Data and Verify_Data in a TSQL batch or via a procedure call from e.g. a .Net client application sometimes works fine, but sometimes it causes the MSSQLSERVER service to go into something like an endless loop while using 100% CPU, especially when I try to install all this on a different machine than my own where I developed the code above (nevertheless, on my own machine it happens too, but less often).
The only thing that can be done is to cancel the executing query and drop the assembly which takes quite long when the CPU is in 100% use.
Can anyone tell me what I have done wrong? Thanks in advance,
Jan
Your stored procedures declare a BIT parameter which the C# methods lack.
To find out whether your assemblies are causing 100% CPU usage, you should log whenever your code executes, and check the generated log file (log4net, BareTail).
Related
I can't find the exact solution to this problem. I have a SQL script that creates another very long script in different steps.
What i do is, along the script, to add new pieces of script to a varchar(max) using concatenation. The final script is so long that it's difficult for me to get it. I use the following as the final instruction:
SELECT [processing-instruction(x)] = #MyScript
FOR XML PATH(''), TYPE;
In this way I can manage to get quite long results with this but sometimes the result is so long that it seems SSMS runs out of memory.
I tried saving my variable #MyScript by selecting it and saving the result as a text or a file but it saves less than 20K characters. I have set the XML max output length as unlimited and it seems to work but when I click on the result cell with the blue content (the xml with the script) then SSMS freezes.
The nice thing is that APPEARENTLY the script is generated quite fast (I am logging with print the different steps) but I can't see the results of my efforts.
Is there some way i can get hold of the content of this lengthy varchar(max) ?
Thanks
Create a procedure that selects the variable as output.
SELECT #MyScript XmlData
FOR XML PATH(''), TYPE;
Then go to the command line and execute:
bcp "exec sp_OutputXml" queryout MyScript.xml -w -T -S <server> -d <database>
If you wanted to do it all with T-SQL you could run the bcp command with xp_cmdshell if you have that enabled on your server.
If you want to save the contents of a MAX type variable or field -- VARCHAR(MAX), NVARCHAR(MAX), and VARBINARY(MAX) -- to a file, you can create a SQLCLR stored procedure or function ( I would choose function so that it can be used inline in a query to saved the contents of a field without first transferring it to a variable, not to mention being set-based and all ).
For saving a string, you can probably get away with doing something as simple as File.WriteAllText. Something along the lines of:
C# code:
using System.Data.SqlTypes;
using Microsoft.SqlServer.Server;
using System.IO;
public class SaveStuff
{
[SqlFunction(IsDeterministic = false, IsPrecise = true)]
public static SqlInt32 SaveToFile([SqlFacet(MaxSize = 500)] SqlString FilePath,
[SqlFacet(MaxSize = -1)] SqlString TextToSave)
{
File.WriteAllText(FilePath.Value, TextToSave.Value);
return TextToSave.Value.Length;
}
}
Please note:
due to accessing the file system, the assembly will need to be registered with PERMISSION_SET = EXTERNAL_ACCESS. While it is easier to set the database to TRUSTWORTHY ON, it is far better to:
sign the assembly and use a password to protect the key file.
create an Asymmetric Key from the DLL
create a Login from that Asymmetric Key
grant the Login the EXTERNAL ACCESS ASSEMBLY permission
the code above is using the system default encoding, which may or may not match how the string is encoded within SQL Server. If necessary, there is another overload of File.WriteAllText that accepts a 3rd input parameter to set the encoding.
the above C# code does not test either input parameter for .IsNull as it is better to create the T-SQL wrapper object using WITH RETURNS NULL ON NULL INPUT as it skips calling this method entirely if either input param is NULL.
Test query:
DECLARE #Bob NVARCHAR(MAX);
SET #Bob = REPLICATE(CONVERT(NVARCHAR(MAX), N'This is just a test, yo! '), 1000000);
SELECT LEN(#Bob); -- 25,000,000
SET STATISTICS TIME ON;
SELECT dbo.SaveToFile(N'C:\TEMP\StackOverflow\z.txt', #Bob); -- 25,000,000
SET STATISTICS TIME OFF;
On my slow laptop, it exported 23.8 MB (25,000,000 bytes) in:
CPU time = 94 ms, elapsed time = 188 ms.
and, adding a 0 to the REPLICATE function, exported 238 MB (250,000,000 bytes) in:
CPU time = 1704 ms, elapsed time = 8714 ms.
(total elapsed time was 33 seconds, so it took 24 seconds to generate the value to be saved)
Now, if you don't want to mess with creating the SQLCLR assembly and the Asymmetric Key, etc., this function (named File_WriteFile), and many others (including File_WriteFileBinary), are available in the SQL# library (which I am the author of). Please note that the File_* functions are only available in the Full version and not in the Free version.
Another option that avoids SSMS from dealing with the full contents of the large variable is having SQL Server email you the contents of that variable as a SQL script. Something like:
sp_send_dbmail #query = 'SELECT #MyScript AS [--MyScript]',
#recipients = 'your#email.address',
#subject = 'My SQL Script',
#attach_query_result_as_file = 1,
#query_attachment_filename = 'DoLotsOfThings.sql',
#query_no_truncate = 1;
Please note that the default maximum file attachment size is 1 MB. I am not sure if that limitation applies to query results that are attached as files, so you might need to first run the following to increase that limit:
sysmail_configure_sp 'MaxFileSize', '52428800'; -- set Max to 50 MB
More info:
sp_send_dbmail
sysmail_configure_sp
Need some help on the below issue:
Case 1 : stored procedure is on server 1 - call is from server1
declare #tempCountry table (countryname char(50))
insert into #tempCountry
exec [database1_server1].[dbo].[getcountrylist]
Select * from #tempCountry
Result: successful execution
Case2 : iIf this same stored procedure is being called from a different server using linked server like this :
declare #tempCountry table (countryname char(50))
insert into #tempCountry
exec [database2_server2].[database1_server1].[dbo].[getcountrylist]
Select * from #tempCountry
Result
Msg 7391, level 16, state 2, line 2
The operation could not be performed because OLEDB provider "SQLNCLI" for linkedserver "Server2_Database2" was unable to begin a distributed transaction.
Case 3
But when tried to execute the stored procedure separately [without temp table insertion] like below
exec [database2_server2].[database1_server1].[dbo].[getcountrylist]
Result: that is executing the stored procedure without any error and returning data.
I forgot to mention that am using SQL Server 2005. As per the server administrator, the feature you've suggested that I use is not available in 2005.
You have (I believe) two options here:
To try to avoid the usage of MSDTC (and all these not pleasant things related to Distributed Transactions) by using OPENQUERY rowset function
/assume (here and below) that [database2_server2] is the name of the linked server/
declare #tempCountry table (countryname char(50))
insert into #tempCountry
select * from openquery([database2_server2], '[database1_server1].[dbo].[getcountrylist]')
select * from #tempCountry
OR
You can set the linked server's option Enable Promotion Of Distributed Transaction to False in order to prevent the local transaction to promote the distributed transaction and therefore use of MSDTC:
EXEC master.dbo.sp_serveroption
#server = N'database2_server2',
#optname = N'remote proc transaction promotion',
#optvalue = N'false'
and your original query should work fine:
declare #tempCountry table (countryname char(50))
insert into #tempCountry
exec [database2_server2].[database1_server1].[dbo].[getcountrylist]
select * from #tempCountry
It is possible to avoid Linked Servers altogether. You can create a SQLCLR stored procedure that makes a standard connection to the remote instance (i.e. Database1).
The C# code below is for a SQLCLR Stored Procedure that:
allows for an optional database name. If empty the current database will be the default database, or if provided it will change to that database after connecting (so that the current database can be different than the default database)
allows for optionally using Impersonation. Without impersonation (the default behavior) the connections are made by the Windows Login that the SQL Server Service is running under (i.e. the "Log On As" account in "Services"). This might not be desired as it does typically provide an elevated level of permissions than the caller usually has. Using Impersonation will maintain the security context of the Login executing the stored procedure, if that Login is associated with a Windows Login. A SQL Server Login does not have a security context and will hence get an error if attempting to use Impersonation.
The ability to toggle Impersonation on and off in the code provided here is for testing purposes so it is easier to see the differences between using Impersonation and not using it. When using this code in a real project, there usually would not be a reason to allow the end-user (i.e. the caller) to change the setting. It is generally safer to use Impersonation. But, the main difficulty in using Impersonation is that it is restricted to the local machine, unless the Windows Login is enabled for Delegation in Active Directory.
should be created on the instance that will be calling Server1: Server2 in Database2
requires a PERMISSION_SET of EXTERNAL_ACCESS. This is best handled by:
signing the Assembly in Visual Studio
in [master], create an Asymmetric Key from the DLL
in [master], create a Login from this new Asymmetric Key
GRANT the EXTERNAL ACCESS ASSEMBLY permission to the new Key-based Login
in [Database2], execute the following:
ALTER ASSEMBLY [NoLinkedServer] WITH PERMISSION_SET = EXTERNAL_ACCESS;
should be executed as:
EXEC dbo.RemoteExec N'Server1', N'Database1', 0;
and:
EXEC dbo.RemoteExec N'Server1', N'Database1', 1;
After each execution, run the following and pay attention to those first two fields:
SELECT [login_name], [original_login_name], *
FROM sys.dm_exec_sessions
WHERE LEFT([program_name], 14) = N'Linked Server?';
The C# code:
using System;
using System.Data;
using System.Data.SqlClient;
using System.Data.SqlTypes;
using System.Security.Principal;
using Microsoft.SqlServer.Server;
public class LinkedServersSuck
{
[Microsoft.SqlServer.Server.SqlProcedure]
public static void RemoteExec(
[SqlFacet(MaxSize = 128)] SqlString RemoteInstance,
[SqlFacet(MaxSize = 128)] SqlString RemoteDatabase,
SqlBoolean UseImpersonation)
{
if (RemoteInstance.IsNull)
{
return;
}
SqlConnectionStringBuilder _ConnectionString =
new SqlConnectionStringBuilder();
_ConnectionString.DataSource = RemoteInstance.Value;
_ConnectionString.Enlist = false;
_ConnectionString.IntegratedSecurity = true;
_ConnectionString.ApplicationName =
"Linked Server? We don't need no stinkin' Linked Server!";
SqlConnection _Connection =
new SqlConnection(_ConnectionString.ConnectionString);
SqlCommand _Command = new SqlCommand();
_Command.CommandType = CommandType.StoredProcedure;
_Command.Connection = _Connection;
_Command.CommandText = #"[dbo].[getcountrylist]";
SqlDataReader _Reader = null;
WindowsImpersonationContext _SecurityContext = null;
try
{
if (UseImpersonation.IsTrue)
{
_SecurityContext = SqlContext.WindowsIdentity.Impersonate();
}
_Connection.Open();
if (_SecurityContext != null)
{
_SecurityContext.Undo();
}
if (!RemoteDatabase.IsNull && RemoteDatabase.Value != String.Empty)
{
// do this here rather than in the Connection String
// to reduce Connection Pool Fragmentation
_Connection.ChangeDatabase(RemoteDatabase.Value);
}
_Reader = _Command.ExecuteReader();
SqlContext.Pipe.Send(_Reader);
}
catch
{
throw;
}
finally
{
if (_Reader != null && !_Reader.IsClosed)
{
_Reader.Close();
}
if (_Connection != null && _Connection.State != ConnectionState.Closed)
{
_Connection.Close();
}
}
return;
}
}
I am trying to convert a database column DATA from varbinary() to varchar(max) in SQL Server 2012.
I am using this code to handle the conversion:
SELECT CONVERT(VARCHAR(MAX), DATA) FROM [dbo].[TABLE_NAME]
and the resulting row is as follows :
VW 6501 Çamaşır
I am having trouble with language specific characters (language is Turkish in my case for now)
How do I get over this encoding problem in SQL Server 2012?
Is there a generic way to do this conversion for any language, considering loss of data/encoding problems for any given language?
This may sound like a rookie question but I really would appreciate any suggestions or answer.
Thank you,
In general, SQL Server does not hold UTF-8 in high regard.
However, .NET has methods to do this and you can get at them via CLR integration.
Compile this using C#:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data.SqlTypes;
using Microsoft.SqlServer.Server;
namespace UtfLib
{
public static class UtfMethods
{
[SqlFunction(IsDeterministic = true, IsPrecise = true)]
public static SqlBinary NVarCharToUtf8(SqlString inputText)
{
if (inputText.IsNull)
return new SqlBinary(); // (null)
return new SqlBinary(Encoding.UTF8.GetBytes(inputText.Value));
}
[SqlFunction(IsDeterministic = true, IsPrecise = true)]
public static SqlString Utf8ToNVarChar(SqlBinary inputBytes)
{
if (inputBytes.IsNull)
return new SqlString(); // (null)
return new SqlString(Encoding.UTF8.GetString(inputBytes.Value));
}
}
}
Import the assembly into your database and create the external functions:
CREATE ASSEMBLY UtfLib
FROM 'C:\UtfLib.dll'
GO
CREATE FUNCTION NVarCharToUtf8 (#InputText NVARCHAR(MAX))
RETURNS VARBINARY(MAX)
AS EXTERNAL NAME UtfLib.[UtfLib.UtfMethods].NVarCharToUtf8
GO
CREATE FUNCTION Utf8ToNVarChar (#InputBytes VARBINARY(MAX))
RETURNS NVARCHAR(MAX)
AS EXTERNAL NAME UtfLib.[UtfLib.UtfMethods].Utf8ToNVarChar
Last step, you have to enable clr
sp_configure 'clr enabled',1
GO
RECONFIGURE
GO
sp_configure 'clr enabled' -- make sure it took
GO
and voilà!
SELECT dbo.Utf8ToNVarChar(DATA) FROM [dbo].[TABLE_NAME]
try NVARCHAR
Select convert (NVARCHAR(max),DATA) FROM [dbo].[TABLE_NAME]
EDIT:
SQL Server does not support handling of UTF8. To convert your binary value you have to write you own function. The easiest way to do that is to use CLR.
You can use this as a model:
How to return an nvarchar(max) in a CLR UDF?
Just replace the regex code with the Encoding.UTF8.GetString
I have quite a few SQLCLR functions and sprocs in my MSSQL 2008 DB. Debugging and logging is always a problem. I have used Microsoft Enterprise Library Logging Application Block a lot in straight C# apps, and was wondering if it was (1) crazy or (2) impossible to layer that into SQLCLR stuff. I really like using a config file to define a rolling text log, Event Log, and SMTP output for different events, so if there is another way to do so, I'm all ears...
Thanks.
It seems like it is possible. I don't know if it's advisable.
One alternative would be defining a trace listener in code, which of course can read the configuration from the database. Another would simple be logging messages to a SQL table and using triggers to enable notifications.
I also do have to question whether the real mistake is that you have CLR stored procs in your database that have so much business logic that they require logging. I'm a big fan of business logic in my database, but I'm wary of CLR stored procs.
If you wanted to use the enterprise application blocks, the config file to edit woulds be C:\Program Files\Microsoft SQL Server\MSSQL10.INSTANCE_NAME\MSSQL\Binn\sqlservr.config. However, sql server does not seem to write values to this file when you restart it. I arrived at this conclusion with the following CLF PROC and UDFs:
using System;
using System.Configuration;
using Microsoft.SqlServer.Server;
namespace LoggedClr
{
public static class AppDomainInfo
{
[SqlFunction]
public static string GetConfigFileName()
{
return AppDomain.CurrentDomain.SetupInformation.ConfigurationFile;
}
[SqlFunction]
public static string GetAppConfigValue(string key)
{
return ConfigurationManager.AppSettings[key];
}
[SqlProcedure]
public static void SetAppConfigValue(string key, string value)
{
ConfigurationManager.AppSettings[key] = value;
}
}
}
Which I loaded and ran using the following T-SQL:
CREATE DATABASE TestAssembly
GO
USE TestAssembly
GO
ALTER DATABASE TestAssembly SET TRUSTWORTHY ON;
GO
ALTER AUTHORIZATION ON DATABASE::TestAssembly TO test
GO
DROP ASSEMBLY LoggedClr
GO
CREATE ASSEMBLY LoggedClr
from 'C:\justin''s projects\TestClr\LoggedClr\LoggedClr\bin\Debug\LoggedClr.dll'
WITH PERMISSION_SET = EXTERNAL_ACCESS
GO
CREATE FUNCTION GetConfigFileName () RETURNS NVARCHAR(MAX) AS
EXTERNAL NAME LoggedClr.[LoggedClr.AppDomainInfo].GetConfigFileName
GO
CREATE FUNCTION GetAppConfigValue (#key nvarchar(max)) RETURNS nvarchar(max) AS
EXTERNAL NAME LoggedClr.[LoggedClr.AppDomainInfo].GetAppConfigValue
GO
CREATE PROCEDURE SetAppConfigValue (#key nvarchar(max), #value nvarchar(max)) AS
EXTERNAL NAME LoggedClr.[LoggedClr.AppDomainInfo].SetAppConfigValue
GO
SELECT dbo.GetConfigFileName()
EXEC dbo.SetAppConfigValue 'justin', 'is a developer'
SELECT dbo.GetAppConfigValue('justin')
This gave me the following results:
------------------------------------------------------------------------------
C:\Program Files\Microsoft SQL Server\MSSQL10.INSTANCE_NAME\MSSQL\Binn\sqlservr.config
(1 row(s) affected)
-------------------------------------------------------------------------
is a developer
(1 row(s) affected)
Is there any regular expression library written in T-SQL (no CLR, no extended SP, pure T-SQL) for SQL Server, and that should work with shared hosting?
Edit:
Thanks, I know about PATINDEX, LIKE, xp_ sps and CLR solutions
I also know it is not the best place for regex, the question is theoretical :)
Reduced functionality is also accepted
How about the PATINDEX function?
The pattern matching in TSQL is not a complete regex library, but it gives you the basics.
(From 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]).
If anybody is interested in using regex with CLR here is a solution. The function below (C# .net 4.5) returns a 1 if the pattern is matched and a 0 if the pattern is not matched. I use it to tag lines in sub queries. The SQLfunction attribute tells sql server that this method is the actual UDF that SQL server will use. Save the file as a dll in a place where you can access it from 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;
}
}
}
In management studio import the dll file via programability -- assemblies -- new assembly
Then run this query:
CREATE FUNCTION RegexContain(#text NVARCHAR(50), #pattern NVARCHAR(50))
RETURNS smallint
AS
EXTERNAL NAME CLR_Functions.[CLR_Functions.myFunctions].RegexContain
Then you should have complete access to the function via the database you stored the assembly in.
Then use in queries like so:
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
There is some basic pattern matching available through using LIKE, where % matches any number and combination of characters, _ matches any one character, and [abc] could match a, b, or c...
There is more info on the MSDN site.
In case anyone else is still looking at this question, http://www.sqlsharp.com/ is a free, easy way to add regular expression CLR functions into your database.
If you are using SQL Server 2016 or above, you can use sp_execute_external_script along with R. It has functions for Regular Expression searches, such as grep and grepl.
Here's an example for email addresses. I'll query some "people" via the SQL Server database engine, pass the data for those people to R, let R decide which people have invalid email addresses, and have R pass back that subset of people to SQL Server. The "people" are from the [Application].[People] table in the [WideWorldImporters] sample database. They get passed to the R engine as a dataframe named InputDataSet. R uses the grepl function with the "not" operator (exclamation point!) to find which people have email addresses that don't match the RegEx string search pattern.
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)))
Note that the appropriate features must be installed on the SQL Server host. For SQL Server 2016, it is called "SQL Server R Services". For SQL Server 2017, it was renamed to "SQL Server Machine Learning Services".
Closing Thoughts
Microsoft's implementation of SQL (T-SQL) doesn't have native support for RegEx. This proposed solution may not be any more desirable to the OP than the use of a CLR stored procedure. But it does offer an additional way to approach the problem.
You can use VBScript regular expression features using OLE Automation. This is way better than the overhead of creating and maintaining an assembly. Please make sure you go through the comments section to get a better modified version of the main one.
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;
If you get SQL Server blocked access to procedure 'sys.sp_OACreate'... error, use sp_reconfigure to enable Ole Automation Procedures. (Yes, unfortunately that is a server level change!)
More information about the Test method is available here
Happy coding