Возвращение таблицы с CLR - PullRequest
16 голосов
/ 11 февраля 2010

Я хочу написать процедуру CLR, которая берет текст и возвращает таблицу со всеми словами в этом тексте. Но я не могу понять, как вернуть стол. Не могли бы вы сказать мне это?

<code>    [Microsoft.SqlServer.Server.SqlFunction]
    public static WhatTypeShouldIWriteHere Function1(SqlString str)
    {
        string[] words = Regex.Split(str, @"\W+").Distinct().ToArray();
        //how to return a table with one column of words?
    }

Спасибо за вашу помощь.

ОБНОВЛЕНО: Мне нужно сделать это для sql-2005

Ответы [ 4 ]

26 голосов
/ 28 июня 2012

Вот полный образец. Я устал искать это сам, и, хотя на него есть ответы, я подумал, что опубликую это, чтобы сохранить свежую ссылку в Интернете.

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;
    }
  }
};
3 голосов
/ 11 февраля 2010

Вы можете вернуть любой список, который реализует IEnumerable. Проверьте это .

0 голосов
/ 24 февраля 2019
    [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;
}

Это было небольшое изменение от кода "Damon Drake"
Этот выполняет поиск вместо того, чтобы возвращать первое найденное значение. так что

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

возвращает

enter image description here

0 голосов
/ 11 февраля 2010

Это новая область SQL Server, вам следует обратиться к этой статье. Который показывает синтаксис табличной функции - это то, что вы хотите создать.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...