2010-11-30 3 views
2

Я запускаю код C# внутри функции CLR и сталкиваюсь с каким-то странным поведением.Ошибка SQL CLR или ошибка?

Когда следующий код работает:

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

Эта ошибка возникает (полную соответствующую трассировку стеки ниже):

Выберите заявления, включенной в функции не может возвращать данные клиента.

Однако, когда я запускаю тот же код, минус «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: Выберите заявления, включенные в функции не может возвращать данные клиенту. System.Data.SqlClient.SqlException: на System.Data.SqlClient.SqlConnection.OnError (SqlException исключением, булева breakConnection) в System.Data.SqlClient.SqlDataReaderSmi.InternalNextResult (Boolean) ignoreNonFatalMessages в 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, метод струнного, DbAsyncResult) в System.Data.SqlClient.SqlCommand.RunExecuteReader (CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, метод String) в System.Data.SqlClie nt.SqlCommand.ExecuteReader (поведение CommandBehavior, метод String) на System.Data.SqlClient.SqlCommand.ExecuteReader() в Aggregation.AggregateDataManager.GetVerticaServer()

В соответствии с просьбой, вот установка на CLR ТВФ:

 [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.

+0

Что такое полный пример кода для функции CLR и как ее использовать. Если это предполагается TVF, вы должны предоставить перечислимый и метод FillRow, которые не выше. Если это ваше точное использование SQLCLR, почему? Было доказано, что это медленнее, чем использование TSQL для этого. – 2010-11-30 02:03:23

ответ

0

Вы пробовали что-то вроде TOP 99.99999 PERCENT?

Смежные вопросы