Aggregate replace in SQL Server?

前端 未结 3 1890
名媛妹妹
名媛妹妹 2021-01-22 03:25

What I\'m trying to achieve is to make dynamic a series of replacements that have to be performed on a certain field. (To make things even easier, I want in fact to remove data,

3条回答
  •  心在旅途
    2021-01-22 03:43

    Once you implement the CLR aggregate function below, you can do:

    SELECT dbo.ReplaceAgg(t.[text], w.badword, w.goodword) // call CLR aggregate function
    FROM [Texts] t CROSS JOIN BadWords w
    GROUP BY t.[text]
    

    CLR aggregate function in C#

    /// 
    /// Allows to apply regex-replace operations to the same string.
    /// For example:
    /// SELECT dbo.ReplaceAgg(t.[text], w.badpattern, "...") 
    /// FROM [Texts] t CROSS JOIN BadPatterns w
    /// GROUP BY t.[text]
    /// 
    [Serializable]
    [Microsoft.SqlServer.Server.SqlUserDefinedAggregate(Format.UserDefined, 
        IsInvariantToDuplicates = true, IsInvariantToOrder = false, 
        IsInvariantToNulls = true, MaxByteSize = -1)]
    public class RegexReplaceAgg : IBinarySerialize
    {
        private string str;
        private string needle;
        private string replacement;
        public void Init()
        {
            str = null;
            needle = null;
            replacement = null;
        }
        public void Accumulate(SqlString haystack, SqlString needle, SqlString replacement)
        {
            // Null values are excluded from aggregate.
            if (needle.IsNull) return;
            if (replacement.IsNull) return;
            if (haystack.IsNull) return;
            str = str ?? haystack.Value;
            this.needle = needle.Value;
            this.replacement = replacement.Value;
            str = Regex.Replace(str, this.needle, this.replacement, RegexOptions.Compiled | RegexOptions.CultureInvariant);
        }
    
        public void Merge(RegexReplaceAgg group)
        {
            Accumulate(group.Terminate(), new SqlString(needle), new SqlString(replacement));
        }
    
        public SqlString Terminate() => new SqlString(str);
    
        public void Read(BinaryReader r)
        {
            str = r.ReadString();
            needle = r.ReadString();
            replacement = r.ReadString();
        }
    
        public void Write(BinaryWriter w)
        {
            w.Write(str);
            w.Write(needle);
            w.Write(replacement);
        }
    }
    

提交回复
热议问题