Returning table with CLR

后端 未结 4 2015
名媛妹妹
名媛妹妹 2021-02-01 07:05

I want to write an CLR procedure which takes a text and returns a table with all the words in this text. But I can\'t figure out how to return a table. Could you please tell me

相关标签:
4条回答
  • 2021-02-01 07:23

    You can return any list that implements an IEnumerable. Check this out.

    0 讨论(0)
  • 2021-02-01 07:28

    Here is a full blown sample. I got tired of searching for this myself and even though this is answered, I thought I would post this just to keep a fresh reference online.

    using System;
    using System.Data.SqlTypes;
    using Microsoft.SqlServer.Server;
    using System.Text.RegularExpressions;
    using System.Collections;
    using System.Collections.Generic;
    
    public partial class UserDefinedFunctions {    
      [SqlFunction]
      public static SqlBoolean RegexPatternMatch(string Input, string Pattern) {    
        return Regex.Match(Input, Pattern).Success ? new SqlBoolean(true) : new SqlBoolean(false);
      }
    
      [SqlFunction]
      public static SqlString RegexGroupValue(string Input, string Pattern, int GroupNumber) {
    
        Match m = Regex.Match(Input, Pattern);
        SqlString value = m.Success ? m.Groups[GroupNumber].Value : null;
    
        return value;
      }
    
      [SqlFunction(DataAccess = DataAccessKind.Read, FillRowMethodName = "FillMatches", TableDefinition = "GroupNumber int, MatchText nvarchar(4000)")]
      public static IEnumerable RegexGroupValues(string Input, string Pattern) {
        List<RegexMatch> GroupCollection = new List<RegexMatch>();
    
        Match m = Regex.Match(Input, Pattern);
        if (m.Success) {
          for (int i = 0; i < m.Groups.Count; i++) {
            GroupCollection.Add(new RegexMatch(i, m.Groups[i].Value));
          }
        }
    
        return GroupCollection;
      }
    
      public static void FillMatches(object Group, out SqlInt32 GroupNumber, out SqlString MatchText) {
        RegexMatch rm = (RegexMatch)Group;
        GroupNumber = rm.GroupNumber;
        MatchText = rm.MatchText;
      }
    
      private class RegexMatch {
        public SqlInt32 GroupNumber { get; set; }
        public SqlString MatchText { get; set; }
    
        public RegexMatch(SqlInt32 group, SqlString match) {
          this.GroupNumber = group;
          this.MatchText = match;
        }
      }
    };
    
    0 讨论(0)
  • 2021-02-01 07:32

    This is a new area of SQL Server, you should consult this article. Which shows the syntax of a table-valued function -- that is what you want to create.

    0 讨论(0)
  • 2021-02-01 07:32
        [SqlFunction(DataAccess = DataAccessKind.Read, FillRowMethodName = "FillMatches", TableDefinition = "GroupNumber int, MatchText nvarchar(4000)")]
    public static IEnumerable Findall(string Pattern, string Input)
    {
        List<RegexMatch> GroupCollection = new List<RegexMatch>();
    
        Regex regex = new Regex(Pattern);
        if (regex.Match(Input).Success)
        {
            int i = 0;
            foreach (Match match in regex.Matches(Input))
            {
                GroupCollection.Add(new RegexMatch(i, match.Groups[0].Value));
                i++;
            }
        }
        return GroupCollection;
    }
    

    That was a slight alteration from the code by "Damon Drake"
    This one does a findall instead of returning the first value found. so

    declare @txt varchar(100) = 'Race Stat 2017-2018 -(FINAL)';
    select * from dbo.findall('(\d+)', @txt)
    

    returns

    0 讨论(0)
提交回复
热议问题