开发者

SQL CLR Error, or Bug?

开发者 https://www.devze.com 2023-01-27 07:21 出处:网络
I\'m running some C# code inside of a CLR Function and running into some strange behavior. When the following code runs:

I'm running some C# code inside of a CLR Function and running into some strange behavior.

When the following code runs:

  SqlCommand cmd = new SqlCommand();
  cmd.CommandText = "SELECT * FROM Vertica_GetVerticaServer_vw WHERE verticaServe开发者_开发技巧r IS NOT NULL ORDER BY NEWID()";

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

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

This error is thrown (full relevant stack trace below):

Select statements included within a function cannot return data to a client.

However, when I run the same code, minus the "ORDER BY NEWID()" (used to randomize the result) and instead run the "ORDER BY NEWID()" inside of the view, I get no errors: Anyone know what's going on here?

  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");

Seems like a bug, but maybe I'm missing something about the NEWID()?

(Note, I tested with GETDATE() instead to see if it was an issue with determinism, and it also worked...).

Full Stack Trace:

---> System.Data.SqlClient.SqlException: Select statements included within a function cannot return data to a client. System.Data.SqlClient.SqlException: at System.Data.SqlClient.SqlConnection.OnError(SqlException exception, Boolean breakConnection) at System.Data.SqlClient.SqlDataReaderSmi.InternalNextResult(Boolean ignoreNonFatalMessages) at System.Data.SqlClient.SqlDataReaderSmi.NextResult() at System.Data.SqlClient.SqlCommand.RunExecuteReaderSmi(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream) at System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, String method, DbAsyncResult result) at System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, String method) at System.Data.SqlClient.SqlCommand.ExecuteReader(CommandBehavior behavior, String method) at System.Data.SqlClient.SqlCommand.ExecuteReader() at Aggregation.AggregateDataManager.GetVerticaServer()

As requested, here's the setup of the 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;
    }

The connection is built by the WeightedInterpreters.


Have you tried something like TOP 99.99999 PERCENT?

0

精彩评论

暂无评论...
验证码 换一张
取 消