【问题标题】:SQL CLR Error, or Bug?SQL CLR 错误,还是错误?
【发布时间】:2011-05-17 14:53:46
【问题描述】:

我在 CLR 函数中运行一些 C# 代码并遇到一些奇怪的行为。

当以下代码运行时:

  SqlCommand cmd = new SqlCommand();
  cmd.CommandText = "SELECT * FROM Vertica_GetVerticaServer_vw WHERE verticaServer IS NOT NULL ORDER BY NEWID()";

  using (cmd.Connection = GetSQLConnection())
  {
    cmd.Connection.Open();
    SqlDataReader r = cmd.ExecuteReader();

    while (r.Read())
    {
      return r.GetString(0);
    }
  }

抛出此错误(下面是完整的相关堆栈跟踪):

函数中包含的 Select 语句无法将数据返回给客户端。

但是,当我运行相同的代码时,减去“ORDER BY NEWID()”(用于随机化结果),而是在视图内运行“ORDER BY NEWID()”,我没有收到任何错误:任何人知道这里发生了什么吗?

  SqlCommand cmd = new SqlCommand();
  cmd.CommandText = "SELECT * FROM Vertica_GetVerticaServer_vw WHERE verticaServer IS NOT NULL");// ORDER BY NEWID()";

  using (cmd.Connection = GetSQLConnection())
  {
    cmd.Connection.Open();
    SqlDataReader r = cmd.ExecuteReader();

    while (r.Read())
    {
      return r.GetString(0);
    }
  }
  throw new Exception("Could not get Vertica Server name");

看起来像一个错误,但也许我错过了关于 NEWID() 的一些内容?

(请注意,我使用 GETDATE() 进行了测试,以查看这是否是确定性问题,并且它也有效...)。

全栈跟踪:

---> System.Data.SqlClient.SqlException:函数中包含的 Select 语句无法将数据返回给客户端。 System.Data.SqlClient.SqlException: 在 System.Data.SqlClient.SqlConnection.OnError(SqlException 异常,布尔 breakConnection) 在 System.Data.SqlClient.SqlDataReaderSmi.InternalNextResult(布尔忽略非致命消息) 在 System.Data.SqlClient.SqlDataReaderSmi.NextResult() 在 System.Data.SqlClient.SqlCommand.RunExecuteReaderSmi(CommandBehavior cmdBehavior,RunBehavior runBehavior,布尔 returnStream) 在 System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior,RunBehavior runBehavior,布尔 returnStream,String 方法,DbAsyncResult 结果) 在 System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior,RunBehavior runBehavior,布尔 returnStream,String 方法) 在 System.Data.SqlClient.SqlCommand.ExecuteReader(CommandBehavior 行为,字符串方法) 在 System.Data.SqlClient.SqlCommand.ExecuteReader() 在 Aggregation.AggregateDataManager.GetVerticaServer()

根据要求,这是 CLR TVF 的设置:

        [Microsoft.SqlServer.Server.SqlFunction(FillRowMethodName = "FillRowAggregates", TableDefinition = "listId int, pricingDate datetime, value decimal", DataAccess=DataAccessKind.Read)]
    public static IEnumerable CalculateListAggregatePricing(int listId, DateTime start, DateTime end, int WeightTypeId)
    {
        DataRequest d = new DataRequest();
        d.Start = start;
        d.Finish = end;
        d.Metric = Metric.GetSharePricingMetric();
        d.Metric.Weight = WeightType.Equal;
        _listId = listId; 
        List<ConstituentInfo> ci = new List<ConstituentInfo>();
        foreach (int i in AggregateDataManager.GetConstituents(listId))
            ci.Add(new ConstituentInfo(i, end));

        switch (WeightTypeId)
        {
            case 0:
                EqualWeightInterpreterForSQLCLR e = new EqualWeightInterpreterForSQLCLR();
                return e.GetIndex(d, ci, false);
            case 1:
                MarketCapWeightInterpreterForSQLCLR mc = new MarketCapWeightInterpreterForSQLCLR();
                return mc.GetIndex(d, ci, false);
            case 2:
                PriceWeightInterpreterForSQLCLR p = new PriceWeightInterpreterForSQLCLR();
                return p.GetIndex(d, ci, false);
        }
        throw new Exception("Invalid Weight Type");

    }

    public static void FillRowAggregates(Object o, out SqlInt32 listId, out SqlDateTime pricingDate, out SqlDecimal value)
    {
        DataPoint dp = (DataPoint)o;

        listId = _listId;
        pricingDate = dp.PricingDate;
        value = (SqlDecimal)dp.Value;
    }

连接由 WeightedInterpreters 构建。

【问题讨论】:

  • CLR 函数的完整代码示例是什么以及如何使用它。如果这应该是 TVF,则必须提供上面没有的 enumerable 和 FillRow 方法。如果这是您对 SQLCLR 的确切使用,为什么?事实证明,这比单独使用 TSQL 要慢。
  • GetSQLConnection 是否使用上下文连接字符串?即return new SqlConnection("context connection=true");.
  • @Johnathan 是的,这是一个 TVF,我会编辑提供功能。该函数实际上会访问一个单独的 DBMS (Vertica) 来检索数据,然后进行一些复杂的聚合,这在 TSQL 中要慢得多。
  • 如果您的视图定义是SELECT TOP 100 PERCENT ... ORDER BY NEWID(),那么这将被优化出来。
  • @Martin Ahh。 TOP 100 PERCENT 得到了优化。我使用的是 TOP 1000,因为基础表中只有 6 行并且我得到了随机结果。

标签: sql-server sql-server-2008 clr sqlclr


【解决方案1】:

您是否尝试过诸如 TOP 99.99999 PERCENT 之类的方法?

【讨论】:

    猜你喜欢
    • 2023-03-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-07-08
    • 2013-05-25
    • 2012-01-29
    • 1970-01-01
    相关资源
    最近更新 更多