2010-11-30 133 views
2

我正在CLR函數中運行一些C#代碼,並運行一些奇怪的行爲。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); 
    } 
    } 

這個錯誤被拋出(全相關堆棧跟蹤如下):包含一個函數中

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(布爾ignoreNonFatalMessages) 在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.SqlClie nt.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構建。

+0

什麼是CLR函數的完整代碼示例以及如何使用它。如果這應該是TVF,則必須提供不在上面的enumerable和FillRow方法。如果這是您對SQLCLR的確切使用,爲什麼?這已被證明比單獨使用TSQL慢。 – 2010-11-30 02:03:23

回答

0

你有沒有試過類似TOP 99.99999 PERCENT的東西?