Saya punya CLR kecil ini yang melakukan fungsi RegEX pada string di kolom.
Saat berjalan pada SQL Server 2014 (12.0.2000) pada Windows Server 2012R2 proses macet
Msg 0, Level 11, Negara 0, Baris 0 Terjadi kesalahan parah pada perintah saat ini. Hasilnya, jika ada, harus dibuang.
dan memberikan stack stack jika saya melakukannya
select count (*) from table where (CLRREGEX,'Regex')
tetapi ketika saya melakukannya
select * from table where (CLRREGEX,'Regex')
mengembalikan baris.
Bekerja dengan sempurna pada build SQL Server yang sama yang berjalan pada Windows 8.1.
Ada ide?
- Sunting Ini sesederhana mungkin
using System;
using System.Collections.Generic;
using System.Text;
using System.Data.SqlTypes; //SqlString, SqlInt32, SqlBoolean
using System.Text.RegularExpressions; //Match, Regex
using Microsoft.SqlServer.Server; //SqlFunctionAttribute
public partial class UserDefinedFunctions
{
public static readonly RegexOptions Options = RegexOptions.IgnorePatternWhitespace | RegexOptions.Multiline;
[SqlFunction]
[Microsoft.SqlServer.Server.SqlFunction(IsDeterministic = true, IsPrecise = true)]
public static SqlBoolean RegExMatch(SqlString input, SqlString pattern)
{
if (input.IsNull || pattern.IsNull) //nulls dont qualify for a match
return SqlBoolean.False;
return Regex.IsMatch(input.Value, pattern.Value, RegexOptions.IgnoreCase);
}
}
Jadi dengan sedikit perubahan ini berfungsi sekarang: Pelajaran utama dalam C # tampaknya sama seperti di TSQL Waspadalah terhadap konversi data implisit.
using System;
using System.Text;
using System.Data.SqlTypes; //SqlString, SqlInt32, SqlBoolean
using System.Text.RegularExpressions; //Match, Regex
using Microsoft.SqlServer.Server; //SqlFunctionAttribute
public partial class UserDefinedFunctions
{
public static readonly RegexOptions Options = RegexOptions.IgnorePatternWhitespace | RegexOptions.Singleline | RegexOptions.Compiled | RegexOptions.IgnoreCase | RegexOptions.CultureInvariant;
[Microsoft.SqlServer.Server.SqlFunction(IsDeterministic = true, IsPrecise = true, DataAccess = DataAccessKind.Read)]
public static SqlBoolean RegExMatch(SqlString input, SqlString pattern)
{
if (input.IsNull || pattern.IsNull) //nulls dont qualify for a match
return SqlBoolean.False;
string sqldata = input.ToString();
string regex = pattern.ToString();
return Regex.IsMatch(sqldata, regex);
}
[SqlFunction]
atribut duplikat . Apakah itu kode yang tepat? Saya tidak berpikir itu akan dikompilasi. Perbedaan Framework versi 2.0 / 3.0 / 3.5 adalah non-masalah karena Anda menggunakan 4.0 / 4.5 / 4.5.x / etc atau apa pun yang ada di server itu karena Anda berada di SQL Server 2014 yang terikat ke CLR versi 4. Apakah server menunjukkan masalah 32-bit? Berapa banyak memori yang dibandingkan dengan server lain? Dan sudahkah Anda memeriksa log SQL Server setelah mendapatkan kesalahan itu?
MatchTimeout
properti baru . Tapi saya tidak berpikir itu benar-benar masalah baik jika Anda hanya melewati 5 karakter maks. Hal ini mungkin bahwa mesin satu ini memiliki rusak menginstal .NET Framework, dan yang dapat diperbaiki sekali trout kegiatan penangkapan ikan telah berhenti ;-). Juga, [0-9].*
sederhana tetapi juga tidak efisien karena cocok dengan semua karakter, jika ada, setelah digit pertama; menggunakan hanya [0-9]
untuk yang IsMatch
lebih baik.
DataAccessKind
ke Read
? Itu hanya memperlambatnya dan Anda tidak melakukan akses data apa pun. Juga, saya menyadari bahwa ini tampaknya berfungsi sekarang, tetapi saya akan berhati-hati dengan menggunakan ToString()
metode yang bertentangan dengan Value
properti karena saya tidak berpikir ToString menangani pengodean dengan benar, atau sesuatu seperti itu. Di mana pengaturan pengumpulan basis data Anda? Tentu saja, saya baru saja membaca kembali salah satu komentar Anda di atas dan melihat bahwa kolomnya adalah VARCHAR, bukan NVARCHAR. Apakah bidang itu memiliki susunan yang berbeda dari basis data?
SqlFunction
metode ini ditandaiIsDeterministic=true
? Apakah majelis ditandai sebagaiSAFE
?