2009-05-11 21 views
1

OK私がかき回すの約3~4分後に、このエラーを取得しておいてください。ここではタイムアウト時間は経過していませんが、タイムアウトしています(コードを参照)?

Timeout expired. The timeout period elapsed prior to completion of the operation or the server is not responding. 
Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code. 

Exception Details: System.Data.SqlClient.SqlException: Timeout expired. The timeout period elapsed prior to completion of the operation or the server is not responding. 

Source Error: 

Line 93: 
Line 94:    DataSet getData; 
Line 95:    getData = SqlHelper.ExecuteDataset(ConfigurationManager.ConnectionStrings["connstr"].ConnectionString, CommandType.StoredProcedure, "Course_NewReportGet_Get_Sav", objPara); 
Line 96: 
Line 97:    foreach (DataRow dr in getData.Tables[0].Rows) 

はコードで、私は適切に何かをしておりませんので、それがなければなりませんが、私は5000秒にタイムアウトを設定すると思います他の何か。プロシージャコールのネストされたループだとわかるでしょう。私はすべての会社を取得してから、すべてのコースを各社に割り当ててから、各コースごとにすべてのユーザーアクティビティのレポートを取得しています。 comapanyあたり2〜70コース、コースレポートあたり8〜1000人のユーザーが企業あたり約250社あります。ここでは多くのデータを扱っています。レポートを取得する最後の呼び出しはかなり大量のストアドプロシージャです。

データを新しいフォームに変換しようとしていますが、これは後で作業する方が速くて簡単ですが、今は解析する必要があります私たちが持っているものを通して新しい方法でそれを掲示する。それはすべて同じデータベースにありますが、私はこれをSQLだけでどうやってやるのかがはっきりしていません。基本的には、レポートツールによって使用されるストアドプロシージャを使用して、データを新しいテーブルにポストするようにしています。しかし、私は、各会社の各コースのための手順を実行し、各企業からの各コースからの報告で返さユーザごとにデータをポストする必要があります...それは...

using System; 
using System.Configuration; 
using System.Data; 
using System.Linq; 
using System.Web; 
using System.Web.Security; 
using System.Web.UI; 
using System.Web.UI.HtmlControls; 
using System.Web.UI.WebControls; 
using System.Web.UI.WebControls.WebParts; 
using System.Xml.Linq; 
using System.Data.SqlClient; 
using Mexico.Data; 

public partial class admin_tools_Optimus : System.Web.UI.Page 
{ 
    protected int step = 0; 
    protected string[] companies = new string[260]; 
    protected string[] coursestrings = new string[260]; 
    protected int total = 0; 
    protected int[] totalcourses = new int[260]; 

    protected void Page_Load(object sender, EventArgs e) 
    { 

    } 

    protected void Proceed(object sender, EventArgs e) 
    { 
     DataSet getCompanies = SqlHelper.ExecuteDataset(ConfigurationManager.ConnectionStrings["connstr"].ConnectionString, CommandType.StoredProcedure, "Companies_All_Get"); 

     int counter = 0; 

     foreach (DataRow dr in getCompanies.Tables[0].Rows) 
     { 
      lstData.Items.Add(dr["companyid"].ToString() + ": " + dr["companyname"].ToString()); 
      companies[counter] = dr["companyid"].ToString(); 
      counter++; 
     } 
     lblCurrentData.Text = counter.ToString() + " companies ready, click next to get all company courses."; 
     total = counter; 

     GetCompanies(); 
    } 


    protected void GetCompanies() 
    { 
     string[,] courses = new string[260, 200]; 

     for (int i = 0; i < total-1; i++) 
     { 
      DataSet getBundles = SqlHelper.ExecuteDataset(ConfigurationManager.ConnectionStrings["connstr"].ConnectionString, CommandType.StoredProcedure, "CompanyCourses_ByCompanyID_Get_Sav", new SqlParameter("@companyid", companies[i])); 

      int counter = 0; 

      foreach (DataRow dr in getBundles.Tables[0].Rows) 
      { 
       courses[i, counter] = dr["bundleid"].ToString(); 
       counter++; 
      } 

      string allID = ""; 

      allID += courses[i, 0]; 

      for (int ii = 0; ii < counter; ii++) 
      { 
       allID += "," + courses[i, ii]; 
      } 
      Response.Write(allID + " <br/>"); 
      coursestrings[i] = allID; 
      totalcourses[i] = counter; 
     } 
     GetUsers(); 
    } 

    protected void GetUsers() 
    { 
     for (int i = 0; i < total - 1; i++) 
     { 
      SqlParameter[] objPara = new SqlParameter[10]; 
      objPara[0] = new SqlParameter("@CompanyID", companies[i]); 
      objPara[1] = new SqlParameter("@CourseID", coursestrings[i]); 
      objPara[2] = new SqlParameter("@DateRangeType", 1); 
      //objPara[3] = new SqlParameter("@StartDate", startDate); 
      //objPara[4] = new SqlParameter("@EndDate", System.DateTime.Now.ToString("MM/dd/yyyy")); 
      objPara[5] = new SqlParameter("@UserName", ""); 
      objPara[6] = new SqlParameter("@StartIndex", 1); 
      objPara[7] = new SqlParameter("@MaximumRows", 100000); 



      DataSet getData; 
      getData = SqlHelper.ExecuteDataset(ConfigurationManager.ConnectionStrings["connstr"].ConnectionString, CommandType.StoredProcedure, "Course_NewReportGet_Get_Sav", objPara); 

      foreach (DataRow dr in getData.Tables[0].Rows) 
      { 
       Response.Write("user: " + dr["userid"].ToString() + "/course: " + dr["bundleid"].ToString() + " - progress: " + dr["viewed"].ToString() + " - scored: " + dr["scored"].ToString() + "<br/><br/>"); 
      } 
     } 
    } 
} 

ページのコード巨大です:

<%@ Page Language="C#" AutoEventWireup="true" CodeFile="Optimus.aspx.cs" Inherits="admin_tools_Optimus" Debug="true" %> 

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> 

<html xmlns="http://www.w3.org/1999/xhtml"> 
<head runat="server"> 
    <title>Untitled Page</title> 
</head> 
<body> 
    <form id="form1" runat="server"> 
    <div> 
     <asp:Label ID="lblCurrentData" runat="server" Text="Click next to get all Companies"/><br /> 
     <asp:Button ID="btnNext" runat="server" Text="Next" OnClick="Proceed" /> 
     <br/> 
     <asp:ListBox ID="lstData" runat="server" height="300" Width="300" /> 
    </div> 
    </form> 
</body> 
</html> 
+1

最終結果としてここで達成しようとしていることを正確に伝えることはできませんが、現在行っている方法ではなく、データベースへの1回の往復でこれを実行できるはずです。そうすれば、私は思うほどの時間を節約できます。 –

+0

ええ、私は同じことを考えていましたが、このように動作させることができれば、これは一度だけのデータ変換に過ぎないので、はるかに労力がかかりません。 – BigOmega

答えて

4

SQLストアドプロシージャを実行しているときにタイムアウトが発生しているようです(例外はSqlException型です)。 Sqlストアドプロシージャの実行のタイムアウトを増やす必要がありますが、SqlHelperクラスでは実行できないと思います。

SqlCommandクラスを使用して、そこにタイムアウトを設定する必要があります。

+0

あなたが言ったとおり、ありがとう – BigOmega

+0

私は助けることができてうれしい! – Joseph

14

あなたがasp.netページからデータベースに話したときに知っておく必要があり5つの異なるタイムアウトがあります。

  1. データベース接続タイムアウト SeはあなたのSQLConnectionオブジェクトで、おそらく接続文字列を介して。
  2. データベースコマンドのタイムアウトSQLCommandオブジェクトに設定します。
  3. ASP.NetスクリプトタイムアウトServer.ScriptTimeout経由でページに設定します。
  4. 他のIISタイムアウト IISによってページに適用されます。このリンクを参照してください:http://msdn.microsoft.com/en-us/library/ms525386.aspx?ppud=4
  5. インターネットブラウザのタイムアウトブラウザ/クライアントは長い間待つだけです。あなたはこれをコントロールしないので、それについて心配する必要はありませんが、あなたはまだそれが存在することを知っておくべきです。

私が最初にリストした4を確認してください。

通常、3分以上がウェイページが読み込まれるのを待つという効果があるとも言います。クエリ時間を正当化するのに十分なデータがあるかもしれませんが、そうであれば、ユーザーが実際に1ページで評価するにはあまりにも多くのデータが必要です。それを分解することを検討してください。しかし、このケースでは、まれに実行される必要のある「レポート」を構築しているように思えます。私はまだそのようなレポートのメリットに疑問を呈していますが(代わりに、手書きでデータを処理するにはあまりにも多くのデータをファクトテーブルや別のデータマイニングのための類似の場所にダンプする)、企業はしばしばそれらを必要としていると思います。

また、あなたのコードを見ると、小さなものの束ではなく、すべてを1つの大きなクエリとして書くことができるかもしれません。これは、結果を組み立てる際にさらに複雑さを犠牲にして、データベースの方がはるかに効率的ですが、結果はより速く実行されます。しかし、頻繁に実行されないものについては、すでにこのようにストアドプロシージャを構築している場合、再書き込みを正当化できない場合があります。

だから、今回は長時間走っているページを渡します。

+0

ありがとう、私は物事をはるかに良く理解するのに役立つ徹底的な投稿!私はn00bです。 +1 – BigOmega

0

これは非常に悪いコードの再利用の例です。必要なすべての入力変数をループさせるストアドプロシージャを再利用する代わりに、ジョインに基づいて情報を選択する新しいセットベースのプロシージャを記述します。はるかに速くなります(あなたが適切に索引付けされていると仮定して)。データベースにアクセスする際に、セットベースの代替が可能な場合は、ループやカーソルを使用して何かを実行する必要はありません。

関連する問題