Ho questo piccolo CLR che svolge una funzione RegEX su una stringa in colonne.
Durante l'esecuzione su SQL Server 2014 (12.0.2000) su Windows Server 2012R2 il processo si arresta in modo anomalo
Messaggio 0, livello 11, stato 0, riga 0 Si è verificato un errore grave nel comando corrente. I risultati, se presenti, devono essere eliminati.
e dà una discarica dello stack se lo faccio
select count (*) from table where (CLRREGEX,'Regex')
ma quando lo faccio
select * from table where (CLRREGEX,'Regex')
restituisce le righe.
Funziona perfettamente sulla stessa build di SQL Server in esecuzione su Windows 8.1.
Qualche idea?
- Modifica È il più semplice possibile
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);
}
}
Quindi, con piccole modifiche, questo funziona ora: la lezione principale in C # sembra essere la stessa di TSQL, attenzione alla conversione implicita dei dati.
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]
attributo duplicato . È questo il codice esatto? Non penso che sarebbe compilare. La distinzione Framework versione 2.0 / 3.0 / 3.5 non è un problema poiché si utilizza 4.0 / 4.5 / 4.5.x / etc o qualsiasi altra cosa si trovi su quel server poiché ci si trova su SQL Server 2014 che è vincolato alla versione 4. di CLR server che mostra il problema a 32 bit? Quanta memoria ha rispetto agli altri server? E hai controllato i log di SQL Server subito dopo aver ricevuto quell'errore?
MatchTimeout
proprietà. Ma non penso che questo sia davvero il problema se stai passando solo 5 caratteri al massimo. Si è possibile che questa macchina ha un corrotto installazione di .NET Framework, e che può essere riparato una volta trota attività di pesca hanno cessato ;-). Inoltre, [0-9].*
è semplice ma anche inefficiente poiché corrisponde a tutti i caratteri, se presenti, dopo la prima cifra; usare solo [0-9]
per un IsMatch
è meglio.
DataAccessKind
a Read
? Questo rallenta e non stai facendo alcun accesso ai dati. Inoltre, mi rendo conto che sembra funzionare ora, ma sarei cauto nell'usare il ToString()
metodo rispetto alla Value
proprietà in quanto non penso che ToString gestisca correttamente le codifiche o qualcosa del genere. Qual è l'impostazione delle regole di confronto dei database? Ovviamente, ho appena riletto uno dei tuoi commenti sopra e ho visto che la colonna è VARCHAR invece di NVARCHAR. Quel campo ha regole di confronto diverse rispetto al database?
SqlFunction
metodo è contrassegnato comeIsDeterministic=true
? L'assemblaggio è contrassegnato comeSAFE
?