AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • 主页
  • 系统&网络
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • 主页
  • 系统&网络
    • 最新
    • 热门
    • 标签
  • Ubuntu
    • 最新
    • 热门
    • 标签
  • Unix
    • 最新
    • 标签
  • DBA
    • 最新
    • 标签
  • Computer
    • 最新
    • 标签
  • Coding
    • 最新
    • 标签
主页 / dba / 问题 / 276791
Accepted
Oscar
Oscar
Asked: 2020-10-09 23:53:25 +0800 CST2020-10-09 23:53:25 +0800 CST 2020-10-09 23:53:25 +0800 CST

如何在 C# SQLCLR 函数中将多个双精度数组作为表返回

  • 772

我所拥有的是一个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);

}
sql-server c#
  • 1 1 个回答
  • 474 Views

1 个回答

  • Voted
  1. Best Answer
    Solomon Rutzky
    2020-10-10T03:50:59+08:002020-10-10T03:50:59+08:00

    如果您想将 3 个数组作为 3 个单独的结果集返回,那么无论是 SQLCLR 还是 T-SQL,这对于函数都是不可能的。您需要创建一个存储过程来返回多个结果集。

    如果 3 个数组表示单个结果集的 3 列,则它们都将具有相同数量的项目,并且其中一个的索引值在概念上与其他的相同索引值相关联(即array1[x]与array2[x]and相关联array3[x],而array1[y]与和array2[y]等array3[y]),那么简单数组是错误的集合类型。您只能返回一个集合,其中集合中的每个项目/元素代表结果集中的一行(或至少有足够的信息来构造所需的行)。当从SqlFunction方法返回时,该单一集合被迭代,FillRowMethod为每个项目/元素调用。一项/元素被传递到FillRowMethod它构造最终的结果集结构和值并将它们传回(因此您有机会在将它们传回之前从原始项目创建和/或转换值)。

    在后一种情况下,您需要创建一个类似于以下内容的类:

    private class volatility
    {
        public double impliedVol;
        public double maturity;
        public double strike;
    }
    

    然后,在您的方法中创建一个通用列表getStrippedCapletVolatilitiesFromCapVolatilityCurve,将一个新项目添加到该集合以使每一行返回,然后返回该列表/集合。FillRowMethod将使用object类型为 的第一个参数(as)调用您volatility。这就是您out将从volatility. 例如:

    private static void FillRow(object obj,
         out SqlDouble impliedVol, out SqlDouble maturity, out SqlDouble strike)
    {
        volatility row = (volatility)obj;
    
        impliedVol = new SqlDouble(row.impliedVol);
        maturity = new SqlDouble(row.maturity);
        strike = new SqlDouble(row.strike);
    }
    

    double[][]现在,可能可以将其作为从 main 返回的二维数组(即 )来处理SqlFunction,但是随后该FillRow方法将被发送 a double[],因为第一个维度被分解为对该FillRow方法的单独调用。我从未尝试过这种特定方法,但它应该如下工作:

    private static void FillRow(object obj,
         out SqlDouble impliedVol, out SqlDouble maturity, out SqlDouble strike)
    {
        double[] row = (double[])obj;
    
        impliedVol = new SqlDouble(row[0]);
        maturity = new SqlDouble(row[1]);
        strike = new SqlDouble(row[2]);
    }
    

    还:

    我突然想到,您甚至可以放弃通用列表/集合并将double[][]数组的内容流式传输到结果集中,一次一个项目/行。来试试这个:

    public static IEnumerable getStrippedCapletVolatilitiesFromCapVolatilityCurve(...)
    {
        //omitted code above this line.
        CapletStipping thisCapletStripping =
           new CapletStipping(maturities, forwardRates, discountingRates, intervalDuration);
        double[][] theseStrippedCapletVols =
           thisCapletStripping.getCapletCurveForGivenStrike(flatVols, strike);
    
        // THIS PART IS DIFFERENT -- begin
        capletVolatilityNode thisCapletVolatilityNode = new capletVolatilityNode();
    
        for (int i = 0; i < theseStrippedCapletVols[0].Length; i += 1)
        {
            thisCapletVolatilityNode.impliedVol = theseStrippedCapletVols[0][i];
            thisCapletVolatilityNode.maturity = theseStrippedCapletVols[1][i];
            thisCapletVolatilityNode.strike = theseStrippedCapletVols[2][i];
    
            yield return thisCapletVolatilityNode; // return rows individually
        }
    
        return; // cannot return anything when using "yield return"
        // THIS PART IS DIFFERENT -- end
    }
    
    private class capletVolatilityNode
    {
        public double impliedVol;
        public double maturity;
        public double strike;
    }
    

    使用时有一些限制yield return,但是如果您的进程允许这种构造,那么这不仅会更快,而且占用的内存也更少。这些好处是由于此代码跳过了将getCapletCurveForGivenStrike()方法的结果复制到单独的集合(即通用列表)的步骤,只是为了将其返回到 T-SQL(在这种情况下,您需要等待它复制集合并使用更多内存)。


    在相关说明中:使用Sql*输入参数的类型而不是标准的 .NET 类型。意思是,使用SqlString代替string和SqlDouble代替double。Value然后,您可以通过所有类型都具有的属性轻松地从那些中获取 .NET 本机类型Sql*(例如,SqlString.Value传回 astring等)。

    有关一般使用 SQLCLR 的更多信息,请访问:SQLCLR 信息

    • 6

相关问题

  • SQL Server - 使用聚集索引时如何存储数据页

  • 我需要为每种类型的查询使用单独的索引,还是一个多列索引可以工作?

  • 什么时候应该使用唯一约束而不是唯一索引?

  • 死锁的主要原因是什么,可以预防吗?

  • 如何确定是否需要或需要索引

Sidebar

Stats

  • 问题 205573
  • 回答 270741
  • 最佳答案 135370
  • 用户 68524
  • 热门
  • 回答
  • Marko Smith

    连接到 PostgreSQL 服务器:致命:主机没有 pg_hba.conf 条目

    • 12 个回答
  • Marko Smith

    如何让sqlplus的输出出现在一行中?

    • 3 个回答
  • Marko Smith

    选择具有最大日期或最晚日期的日期

    • 3 个回答
  • Marko Smith

    如何列出 PostgreSQL 中的所有模式?

    • 4 个回答
  • Marko Smith

    列出指定表的所有列

    • 5 个回答
  • Marko Smith

    如何在不修改我自己的 tnsnames.ora 的情况下使用 sqlplus 连接到位于另一台主机上的 Oracle 数据库

    • 4 个回答
  • Marko Smith

    你如何mysqldump特定的表?

    • 4 个回答
  • Marko Smith

    使用 psql 列出数据库权限

    • 10 个回答
  • Marko Smith

    如何从 PostgreSQL 中的选择查询中将值插入表中?

    • 4 个回答
  • Marko Smith

    如何使用 psql 列出所有数据库和表?

    • 7 个回答
  • Martin Hope
    Jin 连接到 PostgreSQL 服务器:致命:主机没有 pg_hba.conf 条目 2014-12-02 02:54:58 +0800 CST
  • Martin Hope
    Stéphane 如何列出 PostgreSQL 中的所有模式? 2013-04-16 11:19:16 +0800 CST
  • Martin Hope
    Mike Walsh 为什么事务日志不断增长或空间不足? 2012-12-05 18:11:22 +0800 CST
  • Martin Hope
    Stephane Rolland 列出指定表的所有列 2012-08-14 04:44:44 +0800 CST
  • Martin Hope
    haxney MySQL 能否合理地对数十亿行执行查询? 2012-07-03 11:36:13 +0800 CST
  • Martin Hope
    qazwsx 如何监控大型 .sql 文件的导入进度? 2012-05-03 08:54:41 +0800 CST
  • Martin Hope
    markdorison 你如何mysqldump特定的表? 2011-12-17 12:39:37 +0800 CST
  • Martin Hope
    Jonas 如何使用 psql 对 SQL 查询进行计时? 2011-06-04 02:22:54 +0800 CST
  • Martin Hope
    Jonas 如何从 PostgreSQL 中的选择查询中将值插入表中? 2011-05-28 00:33:05 +0800 CST
  • Martin Hope
    Jonas 如何使用 psql 列出所有数据库和表? 2011-02-18 00:45:49 +0800 CST

热门标签

sql-server mysql postgresql sql-server-2014 sql-server-2016 oracle sql-server-2008 database-design query-performance sql-server-2017

Explore

  • 主页
  • 问题
    • 最新
    • 热门
  • 标签
  • 帮助

Footer

AskOverflow.Dev

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve