質問

こちら。C#(下記の)を使用して新しいものを追加した後は問題ありません。

データベースを公開すると、コードジェネレータはIENUMERABLEタイプを認識していないようで、エラーの発生を終了します。以下の生成されたコードからの実際のエラー(AS近くの誤った構文)は明らかであるので、私の質問はにわたって正しいコードを生成し、エラーの原因を避けることができますか?私は手動でCLRを追加することができますが、私はSSDTからすべてをすることを好むでしょう)

現在生成されている

CREATE FUNCTION [dbo].[RegExMatches] (@sourceString [nvarchar](4000), @pattern [nvarchar](4000))
RETURNS /* Error: Unsupported type. */
AS EXTERNAL NAME [CampaignStrategyStaging].[SQLRegEx].[RegExMatches];
.

のようなものを生成するべきです:

CREATE FUNCTION [dbo].[RegExMatches] (@sourceString [nvarchar](4000), @pattern [nvarchar](4000))
RETURNS  TABLE (
    [rowId] int, --RowId each row as it`s ID
    [matchId] int, --ID of particular match (starts from 1)
    [groupId] int, --ID of particular group in RegEx match (GroupID = 0) represents a complete match
    [value] nvarchar(4000) --value of the group
) WITH EXECUTE AS CALLER
AS EXTERNAL NAME [CampaignStrategyStaging].[SQLRegEx].[RegExMatches];
.

CLRのC#:

using System;
using System.Data;
using System.Data.SqlClient;
using System.Data.SqlTypes;
using Microsoft.SqlServer.Server;
using System.Text.RegularExpressions;
using System.Collections;

public class SQLRegEx
{
    private class RegExRow
    {
    /// <summary>
    /// Private class for passing matches of the RegExMatches to the FillRow method
    /// </summary>
    /// <param name=”rowId”>ID of the Row</param>
    /// <param name=”matchId”>ID of the Match</param>
    /// <param name=”groupID”>ID of the Group within the Match</param>
    /// <param name=”value”>Value of the particular group</param>
    public RegExRow(int rowId, int matchId, int groupID, string value)
    {
        RowId = rowId;
        MatchId = matchId;
        GroupID = groupID;
        Value = value;
    }

    public int RowId;
    public int MatchId;
    public int GroupID;
    public string Value;
}

/// <summary>
/// Applies Regular Expression on the Source string and returns value of particular group from withing a specified match
/// </summary>
/// <param name=”sourceString”>Source string on which the regular expression should be applied</param>
/// <param name=”pattern”>Regular Expression pattern</param>
/// <param name=”matchId”>ID of the Match to be returned 1 inex-based</param>
/// <param name=”groupId”>ID of the group from within a match to return. GroupID 0 returns complete match</param>
/// <returns>Value of the Group from within a Match</returns>
[SqlFunction(IsDeterministic=true)]
public static SqlChars RegExMatch(string sourceString, string pattern, int matchId, int groupId)
{
    Match m = null;
    Regex r = new Regex(pattern, RegexOptions.Compiled);

    if (matchId == 1)
    {
        m = r.Match(sourceString);
    }
    else if (matchId > 1)
    {
        MatchCollection mc = r.Matches(sourceString);

        if (mc!=null && mc.Count > matchId-1)
        {
            m = mc[matchId-1];
        }
        else
        {
            m= null;
        }

        ///m = mc != null && mc.Count > matchId – 1 ? mc[matchId - 1] : null;
    }

    return m != null && m.Groups.Count > groupId ? new SqlChars(m.Groups[groupId].Value) : SqlChars.Null;
}

/// <summary>
/// Applies Regular Expression o the Source strings and return all matches and groups
/// </summary>
/// <param name=”sourceString”>Source string on which the regular expression should be applied</param>
/// <param name=”pattern”>Regular Expression pattern</param>
/// <returns>Returns list of RegExRows representing the group value</returns>
[SqlFunction(FillRowMethodName = "FillRegExRow")]
public static IEnumerable RegExMatches(string sourceString, string pattern) 
{
    Regex r = new Regex(pattern, RegexOptions.Compiled);
    int rowId = 0;
    int matchId = 0;
    foreach (Match m in r.Matches(sourceString))
    {
        matchId++;
        for (int i = 0; i < m.Groups.Count; i++)
        {
            yield return new RegExRow(++rowId, matchId, i, m.Groups[i].Value);
        }
    }
}

/// <summary>
/// FillRow method to populate the output table
/// </summary>
/// <param name=”obj”>RegExRow passed as object</param>
/// <param name=”rowId”>ID or the returned row</param>
/// <param name=”matchId”>ID of returned Match</param>
/// <param name=”groupID”>ID of group in the Match</param>
/// <param name=”value”>Value of the Group</param>
public static void FillRegExRow(Object obj, out int rowId, out int matchId, out int groupID, out SqlChars value)
{
    RegExRow r = (RegExRow)obj;
    rowId = r.RowId;
    matchId = r.MatchId;
    groupID = r.GroupID;
    value = new SqlChars(r.Value);
}
.

}

役に立ちましたか?

解決

同僚からの助けの後、私はCLRに2つの変更が必要であることを発見しました:

  1. TabledEfinitionを含めるために必要なSQLFunction []宣言 。(コードは以下の)

    [SqlFunction(FillRowMethodName = "FillRegExRow",
    TableDefinition = "[rowId] int,[matchId] int,[groupId] int, [value] nvarchar(4000)")]
    public static IEnumerable RegExMatches(string sourceString, string pattern)
    
  2. regexrow.regexrowのデータ型はSQLInt32に変更されました。(これは私の元の質問で問題を解決する必要はなかったかもしれません)

  3. だから全体のコードは次のように変更されました:

    using System;
    using System.Data;
    using System.Data.SqlClient;
    using System.Data.SqlTypes;
    using Microsoft.SqlServer.Server;
    using System.Text.RegularExpressions;
    using System.Collections;
    
    public class SQLRegEx
    {
        private class RegExRow
        {
        /// <summary>
        /// Private class for passing matches of the RegExMatches to the FillRow method
        /// </summary>
        /// <param name=”rowId”>ID of the Row</param>
        /// <param name=”matchId”>ID of the Match</param>
        /// <param name=”groupID”>ID of the Group within the Match</param>
        /// <param name=”value”>Value of the particular group</param>
        public RegExRow(SqlInt32 rowId, SqlInt32 matchId, SqlInt32 groupID, string value)
        {
    
            RowId = rowId;
            MatchId = matchId;
            GroupID = groupID;
            Value = value;
        }
    
        public SqlInt32 RowId;
        public SqlInt32 MatchId;
        public SqlInt32 GroupID;
        public string Value;
    }
    
    /// <summary>
    /// Applies Regular Expression on the Source string and returns value of particular group from withing a specified match
    /// </summary>
    /// <param name=”sourceString”>Source string on which the regular expression should be applied</param>
    /// <param name=”pattern”>Regular Expression pattern</param>
    /// <param name=”matchId”>ID of the Match to be returned 1 inex-based</param>
    /// <param name=”groupId”>ID of the group from within a match to return. GroupID 0 returns complete match</param>
    /// <returns>Value of the Group from within a Match</returns>
    [SqlFunction(IsDeterministic=true)]
    public static SqlChars RegExMatch(string sourceString, string pattern, int matchId, int groupId)
    {
        Match m = null;
        Regex r = new Regex(pattern, RegexOptions.Compiled);
    
        if (matchId == 1)
        {
            m = r.Match(sourceString);
        }
        else if (matchId > 1)
        {
            MatchCollection mc = r.Matches(sourceString);
    
            if (mc!=null && mc.Count > matchId-1)
            {
                m = mc[matchId-1];
            }
            else
            {
                m= null;
            }
    
            ///m = mc != null && mc.Count > matchId – 1 ? mc[matchId - 1] : null;
        }
    
        return m != null && m.Groups.Count > groupId ? new SqlChars(m.Groups[groupId].Value) : SqlChars.Null;
    }
    
    /// <summary>
    /// Applies Regular Expression o the Source strings and return all matches and groups
    /// </summary>
    /// <param name=”sourceString”>Source string on which the regular expression should be applied</param>
    /// <param name=”pattern”>Regular Expression pattern</param>
    /// <returns>Returns list of RegExRows representing the group value</returns>
    /// 
    
    [SqlFunction(FillRowMethodName = "FillRegExRow",
                TableDefinition = "rowId int,[matchId] int,[groupId] int, [value] nvarchar(4000)")]
    public static IEnumerable RegExMatches(string sourceString, string pattern)
    {
        Regex r = new Regex(pattern, RegexOptions.Compiled);
        int rowId = 0;
        int matchId = 0;
        foreach (Match m in r.Matches(sourceString))
        {
            matchId++;
            for (int i = 0; i < m.Groups.Count; i++)
            {
                ++rowId;
                yield return new RegExRow(rowId, matchId, i, m.Groups[i].Value);
            }
        }
    }
    
    /// <summary>
    /// FillRow method to populate the output table
    /// </summary>
    /// <param name=”obj”>RegExRow passed as object</param>
    /// <param name=”rowId”>ID or the returned row</param>
    /// <param name=”matchId”>ID of returned Match</param>
    /// <param name=”groupID”>ID of group in the Match</param>
    /// <param name=”value”>Value of the Group</param>
    public static void FillRegExRow(Object obj, out SqlInt32 rowId, out SqlInt32 matchId, out SqlInt32 groupID, out SqlChars value)
    {
        RegExRow r = (RegExRow)obj;
        rowId = r.RowId;
        matchId = r.MatchId;
        groupID = r.GroupID;
        value = new SqlChars(r.Value);
    }
    
    .

    }

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top