ฉันมี CLR ขนาดเล็กนี้ที่ทำหน้าที่ RegEX ในสตริงในคอลัมน์
เมื่อทำงานบน SQL Server 2014 (12.0.2000) บน Windows Server 2012R2 กระบวนการขัดข้อง
ข่าวสารเกี่ยวกับ 0, ระดับ 11, สถานะ 0, บรรทัด 0 มีข้อผิดพลาดร้ายแรงเกิดขึ้นกับคำสั่งปัจจุบัน ควรยกเลิกผลลัพธ์หากมี
และให้กองการถ่ายโอนข้อมูลถ้าฉันทำ
select count (*) from table where (CLRREGEX,'Regex')
แต่เมื่อฉันทำ
select * from table where (CLRREGEX,'Regex')
มันจะส่งคืนแถว
ทำงานได้อย่างสมบูรณ์บน SQL Server รุ่นเดียวกับที่ทำงานบน Windows 8.1
ความคิดใด ๆ
- แก้ไขมันง่ายอย่างที่ควรเป็น
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);
}
}
ดังนั้นโดยการเปลี่ยนแปลงเล็ก ๆ น้อย ๆ งานนี้ตอนนี้: บทเรียนหลักใน C # ดูเหมือนว่าจะเหมือนกับใน TSQL ระวังการแปลงข้อมูลโดยนัย
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]
แอตทริบิวต์ซ้ำกัน นั่นคือรหัสที่แน่นอน? ฉันไม่คิดว่าจะรวบรวม Framework รุ่น 2.0 / 3.0 / 3.5 มีความแตกต่างไม่ใช่ประเด็นตามที่คุณใช้ 4.0 / 4.5 / 4.5.x / etc หรือสิ่งที่อยู่บนเซิร์ฟเวอร์นั้นเนื่องจากคุณอยู่ใน SQL Server 2014 ซึ่งถูกผูกไว้กับรุ่น CLR 4 เซิร์ฟเวอร์แสดงปัญหา 32 บิตหรือไม่ มันมีหน่วยความจำเท่าไหร่เมื่อเทียบกับเซิร์ฟเวอร์อื่น ๆ ? และคุณได้ตรวจสอบบันทึก SQL Server หลังจากได้รับข้อผิดพลาดนั้นหรือไม่?
MatchTimeout
คุณสมบัติใหม่ได้ แต่ฉันไม่คิดว่าเป็นปัญหาจริง ๆ ถ้าคุณผ่านเพียง 5 ตัวอักษรสูงสุด มันเป็นไปได้ว่าเครื่องนี้คนมีความเสียหายติดตั้งของ .NET Framework และที่สามารถได้รับการซ่อมแซมครั้งหนึ่งกิจกรรมการประมงปลาเทราท์ได้หยุด ;-) นอกจากนี้ยัง[0-9].*
ง่าย แต่ไม่มีประสิทธิภาพเนื่องจากตรงกับตัวอักษรทั้งหมดหากมีหลังจากตัวเลขตัวแรก ใช้เพียง[0-9]
เพื่อIsMatch
จะดีกว่า
DataAccessKind
ถึงเปลี่ยนไปRead
? นั่นทำให้ช้าลงและคุณไม่ได้เข้าถึงข้อมูลใด ๆ นอกจากนี้ฉันรู้ว่าตอนนี้ดูเหมือนว่าจะทำงานได้ แต่ฉันจะต้องระมัดระวังในการใช้ToString()
วิธีการที่ตรงข้ามกับValue
สถานที่ให้บริการที่ฉันไม่คิดว่า ToString จัดการการเข้ารหัสอย่างถูกต้องหรือสิ่งที่ชอบ การเปรียบเทียบฐานข้อมูลของคุณตั้งไว้เป็นเท่าไหร่? แน่นอนฉันเพิ่งอ่านความคิดเห็นของคุณข้างบนอีกครั้งและดูว่าคอลัมน์นั้นเป็น VARCHAR แทนที่จะเป็น NVARCHAR ฟิลด์นั้นมีการเปรียบเทียบที่แตกต่างจากฐานข้อมูลหรือไม่
SqlFunction
วิธีการทำเครื่องหมายว่าIsDeterministic=true
? ชุดประกอบทำเครื่องหมายว่าเป็นSAFE
?