J'ai ce petit CLR qui fait une fonction RegEX sur une chaîne de colonnes.
Lors de l'exécution sur SQL Server 2014 (12.0.2000) sur Windows Server 2012R2, le processus se bloque avec
Msg 0, niveau 11, état 0, ligne 0 Une erreur grave s'est produite sur la commande actuelle. Le cas échéant, les résultats doivent être ignorés.
et donne un vidage de la pile si je fais
select count (*) from table where (CLRREGEX,'Regex')
mais quand je fais
select * from table where (CLRREGEX,'Regex')
il renvoie les lignes.
Fonctionne parfaitement sur la même version de SQL Server exécutée sur Windows 8.1.
Des idées?
- Modifier C'est aussi simple que possible
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);
}
}
Donc, par petits changements, cela fonctionne maintenant: la leçon principale en C # semble être la même que dans TSQL, méfiez-vous de la conversion implicite des données.
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]
attribut en double . Est-ce le code exact? Je ne pense pas que cela se compilerait. La distinction Framework version 2.0 / 3.0 / 3.5 n'est pas un problème car vous utilisez 4.0 / 4.5 / 4.5.x / etc ou tout ce qui se trouve sur ce serveur puisque vous êtes sur SQL Server 2014 qui est lié à CLR version 4. Est-ce que serveur montrant le problème 32 bits? Combien de mémoire possède-t-il par rapport aux autres serveurs? Et avez-vous vérifié les journaux SQL Server juste après avoir obtenu cette erreur?
MatchTimeout
propriété. Mais je ne pense pas que ce soit vraiment le problème non plus si vous ne passez que 5 caractères max. Il est possible que cette machine ait une installation corrompue du .NET Framework, et qu'elle puisse être réparée une fois que les activités de pêche à la truite ont cessé ;-). En outre, [0-9].*
est simple mais aussi inefficace car il correspond à tous les caractères, le cas échéant, après le premier chiffre; utiliser juste [0-9]
pour un IsMatch
est mieux.
DataAccessKind
pour Read
? Cela ralentit simplement et vous ne faites aucun accès aux données. De plus, je me rends compte que cela semble fonctionner maintenant, mais je serais prudent avec l'utilisation de la ToString()
méthode par opposition à la Value
propriété car je ne pense pas que ToString gère correctement les encodages, ou quelque chose comme ça. À quoi sert le classement de vos bases de données? Bien sûr, je viens de relire l'un de vos commentaires ci-dessus et de voir que la colonne est VARCHAR au lieu de NVARCHAR. Ce champ a-t-il un classement différent de celui de la base de données?
SqlFunction
méthode est-elle marquée commeIsDeterministic=true
? L'assemblage est-il marqué commeSAFE
?