La création d'une fonction SQL CLR est la solution idéale. Ils sont extrêmement rapides et puissants. Ce serait rapide et efficace car vous n'auriez pas à changer de code existant, et vous pourriez spécifier toutes les informations dont vous avez besoin directement dans vos instructions SQL.
La fonction SQL CLR peut accepter une chaîne d'entrée, ainsi que d'autres paramètres spécifiant l'information que vous souhaitez extraire de la chaîne d'entrée. Vous pouvez ensuite trier les valeurs de retour de la fonction. En particulier, je créerais une fonction générique qui accepte trois paramètres: une chaîne d'entrée, une expression régulière et un nom de groupe. Cette fonction vous permet de passer votre champ de base de données et une expression régulière avec des groupes nommés directement dans l'instruction SQL. La fonction SQL CLR créait une expression régulière, la testait par rapport à la chaîne et renvoyait finalement la valeur du groupe correspondant ou null s'il n'y avait pas de correspondance ou si le groupe ne correspondait pas (si le groupe était facultatif). Idéalement, vous voudriez passer la même expression régulière à chaque appel (peut-être en tant que variable comme @regex), pour profiter de toute mise en cache CLR de l'expression régulière compilée. Le résultat final serait très flexible et rapide.
Les options d'expressions régulières peuvent être spécifiées en ligne dans le modèle comme ceci: "(? Imnsx-imnsx: sous-expression)". Voir: msdn.microsoft.com/en-us/library/yd1hzczs.aspx
Le code pour une telle fonction ressemblerait à quelque chose comme ceci:
[SqlFunction(IsDeterministic=true,IsPrecise=true,DataAccess=DataAccessKind.None,SystemDataAccess=SystemDataAccessKind.None)]
public static SqlString RegexMatchNamedGroup(SqlChars input, SqlString pattern, SqlString group_name)
{
Regex regex = new Regex(pattern.Value);
Match match = regex.Match(new string(input.Value));
if (!match.Success) //return null if match failed
return SqlString.Null;
if (group_name.IsNull) //return entire string if matched when no group name is specified
return match.Value;
Group group = match.Groups[group_name.Value];
if (group.Success)
return group.Value; //return matched group value
else
return SqlString.Null; //return null if named group was not matched
}
Votre instruction SQL pouvez alors trier sur des morceaux de vos informations comme ceci:
declare @regex nvarchar(2000) = '^(?<Major>\d{1,3})\.(?<Minor>\d{1,3})';
select VersionNumber
from YourTable
order by
Cast(RegexMatchNamedGroup(VersionNumber, @regex, 'Major') as int),
Cast(RegexMatchNamedGroup(VersionNumber, @regex, 'Minor') as int)
Quel format est-il stocké exactement? – gbn