Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/21.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何获取SQL字符串';CLR函数中的排序规则?_C#_Sql Server_Sql Server 2008 R2_Collation_Sqlclr - Fatal编程技术网

C# 如何获取SQL字符串';CLR函数中的排序规则?

C# 如何获取SQL字符串';CLR函数中的排序规则?,c#,sql-server,sql-server-2008-r2,collation,sqlclr,C#,Sql Server,Sql Server 2008 R2,Collation,Sqlclr,我正在用C#编写一个Levenshtein距离函数来计算两个字符串之间的编辑距离。问题是,我希望使用不同的排序规则多次调用该方法,但只有一个排序规则能够通过SQL-to-CLR接口—这是数据库的默认排序规则 以下是CLR函数的代码: [SqlFunction(IsDeterministic=true,Name=“LevenshteinDistance”)] 公共静态SqlInt64距离(SqlString textA、SqlString textB) { //获取支持排序规则的比较器,以便进行字

我正在用C#编写一个Levenshtein距离函数来计算两个字符串之间的编辑距离。问题是,我希望使用不同的排序规则多次调用该方法,但只有一个排序规则能够通过SQL-to-CLR接口—这是数据库的默认排序规则

以下是CLR函数的代码:

[SqlFunction(IsDeterministic=true,Name=“LevenshteinDistance”)]
公共静态SqlInt64距离(SqlString textA、SqlString textB)
{
//获取支持排序规则的比较器,以便进行字符串/字符比较
//将匹配输入的指定排序规则
var aCompareInfo=textA.CompareInfo;
var compareOptions=ConvertCompareOptions(textA.SqlCompareOptions);
var aLength=textA.Value.Length;
var bLength=textB.Value.Length;
//退化病例
if(aCompareInfo.Compare(textA.Value,0,aLength,textB.Value,0,bLength,compareOptions)==0){return 0;}
如果(aLength==0){return bLength;}
如果(bLength==0){return aLength;}
//创建两个整数距离的工作向量
var previousDistances=新SqlInt64[最大值(aLength,bLength)+1];
var currentDistances=新SqlInt64[最大值(aLength,bLength)+1];
//初始化上一行距离(上一行距离)
//此行是[0][i]:编辑空文本的距离A
//距离只是要从textB中删除的字符数
对于(变量i=0;i
将CLR程序集部署到SQL Server(2008 R2)并按如下方式调用后:

print dbo.levenshteindication('abc'比较拉丁语1\u General\u CI\u AI,'abc'比较拉丁语1\u General\u CI\u AI)
打印dbo.LevenshteInstitution('abc'校对拉丁语1_General_CS_AS_KS_WS,N'abc'校对拉丁语1_General_CS_AS_KS_WS)
两个调用都返回零(0)。因为我为第二个调用指定了区分大小写的排序规则,所以我希望第二个调用返回三(3)


使用SQL Server中的CLR函数,是否可以指定数据库默认值以外的排序规则,并在CLR函数中使用它们?如果是,怎么做?

在互联网上看不到任何替代方案或对这个问题的回答,我决定指定所需的排序规则属性作为函数参数,并根据输入或从数据库传入的默认排序规则选择
CultureInfo
对象和
CompareOptions

[SqlFunction(IsDeterministic=true,Name=“LevenshteinDistance”)]
公共静态SqlInt64距离(SqlString textA、SqlString textB、int?lcid、bool?不区分大小写、bool?不区分重音、bool?不区分假名、bool?不区分宽度)
{
//获取支持排序规则的比较器,以便进行字符串/字符比较
//将匹配输入的指定排序规则
//var aCompareInfo=textA.CompareInfo;
var aCompareInfo=CultureInfo.GetCultureInfo(lcid??textA.lcid).CompareInfo;
//var compareOptions=ConvertCompareOptions(textA.SqlCompareOptions);
var compareOptions=GetCompareOptions(不区分大小写,不区分重音,不区分假名,不区分全半角);
//…更多代码。。。
//第一次比较
if(aCompareInfo.Compare(textA.Value,0,aLength,textB.Value,0,bLength,compareOptions)==0){return 0;}
//…更多代码。。。
var成本=(a比较信息比较(textA.Value,i,1,textB.Value,j,1,compareOptions)=0)?0:1;
//…更多代码。。。
}
私有静态CompareOptions GetCompareOptions(布尔?不区分大小写,布尔?不区分重音,布尔?不区分假名,布尔?不区分全半角)
{
var compareOptions=compareOptions.None;
compareOptions |=(不区分大小写??错误)?compareOptions.IgnoreCase:compareOptions.None;
compareOptions |=(AccentSensitive?false)?compareOptions.IgnoreNonSpace:compareOptions.None;
compareOptions |=(不区分假名??false)?compareOptions.IgnoreKanaType:compareOptions.None;
compareOptions |=(不区分宽度??错误)?compareOptions.IgnoreWidth:compareOptions.None;
返回比较;
}
在更新我的程序集和UDF声明后,我可以这样调用函数:

print dbo.levenshteindication('abc','abc',null,1,1,1)
打印dbo.levenshteindication('abc','abc',null,0,0,0)
现在,第一个调用返回0(数据库默认区域性,一切不敏感),而第二个调用返回3(数据库默认区域性,一切敏感)

如何在CLR函数中获取SQL字符串的排序规则

不幸的是,你不能。根据的TechNet页面,在“参数排序”部分:

当您创建公共语言运行时(CLR)例程,并且绑定到该例程的CLR方法的参数类型为SqlString时,SQL Server将使用包含调用例程的数据库的默认排序规则创建该参数的实例。如果一个参数
SELECT dbo.ClrCollationTest(N'Anything' collate latin1_general_cs_as),
       dbo.ClrCollationTest(N'Anything' collate SQL_Latin1_General_CP1_CI_AS);
public static SqlBoolean ClrCollationTest(object anything)
{
    if (anything is SqlString)
        return new SqlBoolean(((SqlString)anything).SqlCompareOptions.HasFlag(SqlCompareOptions.IgnoreCase));
    else throw new ArgumentException(anything.GetType().Name + " is not a valid parameter data type.  SqlString is required.");
}