我所拥有的是一个SqlFunction
产生 3 个双精度数组的 CLR。我希望此函数返回适当的内容,以便FillRowMethod
可以将其作为 T-SQL 中的表输出给我。它适用于 1 个阵列,但我无法将其扩展到多个阵列。我主要不确定从我的方法返回什么。下面的一些代码:
[SqlFunction(DataAccess = DataAccessKind.Read, FillRowMethodName = "FillRow",
TableDefinition = "impliedVol float, maturity float, strike float")]
public static IEnumerable getStrippedCapletVolatilitiesFromCapVolatilityCurve(
string uploadDate, double strike, double yearsForward, double intervalDuration,
string curve, string surface)
//Create 3 arrays of doubles
double[] array1;
double[] array2;
double[] array3;
return [???];
}
public static void FillRow(object obj,
out SqlDouble impliedVol, out SqlDouble maturity, out SqlDouble strike)
{
//impliedVol = (double)obj; //This is what I do if only returning one array
}
编辑:
根据反馈,这是我尝试的新解决方案。
public static IEnumerable getStrippedCapletVolatilitiesFromCapVolatilityCurve(string uploadDate, double strike, double yearsForward, double intervalDuration, string curve, string surface)
{
//omitted code above this line.
CapletStipping thisCapletStripping = new CapletStipping(maturities, forwardRates, discountingRates, intervalDuration);
double[][] theseStrippedCapletVols = thisCapletStripping.getCapletCurveForGivenStrike(flatVols, strike);
List<capletVolatilityNode> capletVolatilitiesList = new List<capletVolatilityNode>(theseStrippedCapletVols[0].Length);
for (int i = 0; i < theseStrippedCapletVols[0].Length; i += 1)
{
capletVolatilityNode thisCapletVolatilityNode = new capletVolatilityNode(theseStrippedCapletVols[0][i], theseStrippedCapletVols[1][i], theseStrippedCapletVols[2][i]);
capletVolatilitiesList[i] = thisCapletVolatilityNode;
}
return capletVolatilitiesList; // theseStrippedCapletVols;
}
public class capletVolatilityNode
{
public double impliedVol;
public double maturity;
public double strike;
public capletVolatilityNode(double impliedVol_, double maturity_, double strike_)
{
impliedVol = impliedVol_;
maturity = maturity_;
strike = strike_;
}
}
public static void FillRow(Object obj, out SqlDouble impliedVol, out SqlDouble maturity, out SqlDouble strike)
{
capletVolatilityNode row = (capletVolatilityNode)obj;
impliedVol = Convert.ToDouble(row.impliedVol);
maturity = Convert.ToDouble(row.maturity);
strike = Convert.ToDouble(row.strike);
}
如果您想将 3 个数组作为 3 个单独的结果集返回,那么无论是 SQLCLR 还是 T-SQL,这对于函数都是不可能的。您需要创建一个存储过程来返回多个结果集。
如果 3 个数组表示单个结果集的 3 列,则它们都将具有相同数量的项目,并且其中一个的索引值在概念上与其他的相同索引值相关联(即
array1[x]
与array2[x]
and相关联array3[x]
,而array1[y]
与和array2[y]
等array3[y]
),那么简单数组是错误的集合类型。您只能返回一个集合,其中集合中的每个项目/元素代表结果集中的一行(或至少有足够的信息来构造所需的行)。当从SqlFunction
方法返回时,该单一集合被迭代,FillRowMethod
为每个项目/元素调用。一项/元素被传递到FillRowMethod
它构造最终的结果集结构和值并将它们传回(因此您有机会在将它们传回之前从原始项目创建和/或转换值)。在后一种情况下,您需要创建一个类似于以下内容的类:
然后,在您的方法中创建一个通用列表
getStrippedCapletVolatilitiesFromCapVolatilityCurve
,将一个新项目添加到该集合以使每一行返回,然后返回该列表/集合。FillRowMethod
将使用object
类型为 的第一个参数(as)调用您volatility
。这就是您out
将从volatility
. 例如:double[][]
现在,可能可以将其作为从 main 返回的二维数组(即 )来处理SqlFunction
,但是随后该FillRow
方法将被发送 adouble[]
,因为第一个维度被分解为对该FillRow
方法的单独调用。我从未尝试过这种特定方法,但它应该如下工作:还:
我突然想到,您甚至可以放弃通用列表/集合并将
double[][]
数组的内容流式传输到结果集中,一次一个项目/行。来试试这个:使用时有一些限制
yield return
,但是如果您的进程允许这种构造,那么这不仅会更快,而且占用的内存也更少。这些好处是由于此代码跳过了将getCapletCurveForGivenStrike()
方法的结果复制到单独的集合(即通用列表)的步骤,只是为了将其返回到 T-SQL(在这种情况下,您需要等待它复制集合并使用更多内存)。在相关说明中:使用
Sql*
输入参数的类型而不是标准的 .NET 类型。意思是,使用SqlString
代替string
和SqlDouble
代替double
。Value
然后,您可以通过所有类型都具有的属性轻松地从那些中获取 .NET 本机类型Sql*
(例如,SqlString.Value
传回 astring
等)。有关一般使用 SQLCLR 的更多信息,请访问:SQLCLR 信息