我正在尝试重用找到的一些代码here http://www.pawlowski.cz/2010/09/sql-server-2005-and-sql-server-2008-regular-expressions-and-pattern-matching-2/。使用 c# 添加新的后(如下所示)似乎没问题。
然而,当我去发布数据库时,代码生成器似乎无法识别 IEnumerable 类型并最终产生错误。下面生成的代码中的实际错误(AS 附近的语法不正确)是显而易见的,所以我的问题是如何让 SSDT 生成正确的代码并避免错误原因?(我假设我可以手动添加 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);
}
}