2011-09-19 172 views
0

我試圖檢索基於Year,Faculty,Quarter和Course的信息。取決於用戶希望成爲什麼樣的特定人員(年度,季度,課程等)。動態SQL查詢

string a = ""; 

    if (DDLYear.SelectedValue == "Select") 
    { 
     return; 
    } 
    else 
    { 
     a = DDLYear.SelectedValue; 
    } 

if (DDLFaculty.SelectedValue != "Select") 
      { 
       arrFields.Add("Employee.Employee_ID = " + DDLFaculty.SelectedValue); 
      } 
      if (DDLQuarter.SelectedValue != "Select") 
      { 
       arrFields.Add("Quarter.Quarter_Name = " + DDLQuarter.SelectedValue); 
      } 
      if (DDLCourse.SelectedValue != "Select") 
      { 
       arrFields.Add("Course.Title = " + DDLCourse.SelectedValue); 
      } 

Custom.SelectCommand = Custom.SelectCommand = 
    "SELECT AVG(Rating.Score) AS YearsAverageScore 
    FROM Rating INNER JOIN Survey ON Rating.Survey_ID = Survey.Survey_ID 
    INNER JOIN Course_Quarter ON Survey.CourseQuarter_ID = Course_Quarter.CourseQuarter_ID 
    INNER JOIN Quarter ON Course_Quarter.Quarter_ID = Quarter.Quarter_ID 
    INNER JOIN Employee ON Course_Quarter.Employee_ID = Employee.Employee_ID 
    WHERE (Quarter.Year = " + a + String.Join("and ", arrFields.ToArray()) + ")"; 

當我嘗試檢索員工「A」我碰到一個錯誤的2000年信息:「附近有語法錯誤mployee'」。除了Employee中的代碼外,代碼中沒有「mployee」。當我添加「僱員」之間的空間我碰到了同樣的錯誤,除了它說:附近有語法錯誤「員工」」

錯誤報告:

Incorrect syntax near 'Employee'. 
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: Incorrect syntax near 'Employee'. 

Source Error: 

An unhandled exception was generated during the execution of the current web request. Information regarding the origin and location of the exception can be identified using the exception stack trace below. 

Stack Trace: 


[SqlException (0x80131904): Incorrect syntax near 'Employee'.] 
    System.Data.SqlClient.SqlConnection.OnError(SqlException exception, Boolean breakConnection) +2073502 
    System.Data.SqlClient.SqlInternalConnection.OnError(SqlException exception, Boolean breakConnection) +5064460 
    System.Data.SqlClient.TdsParser.ThrowExceptionAndWarning() +234 
    System.Data.SqlClient.TdsParser.Run(RunBehavior runBehavior, SqlCommand cmdHandler, SqlDataReader dataStream, BulkCopySimpleResultSet bulkCopyHandler, TdsParserStateObject stateObj) +2275 
    System.Data.SqlClient.SqlDataReader.ConsumeMetaData() +33 
    System.Data.SqlClient.SqlDataReader.get_MetaData() +86 
    System.Data.SqlClient.SqlCommand.FinishExecuteReader(SqlDataReader ds, RunBehavior runBehavior, String resetOptionsString) +311 
    System.Data.SqlClient.SqlCommand.RunExecuteReaderTds(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, Boolean async) +987 
    System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, String method, DbAsyncResult result) +162 
    System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, String method) +32 
    System.Data.SqlClient.SqlCommand.ExecuteReader(CommandBehavior behavior, String method) +141 
    System.Data.SqlClient.SqlCommand.ExecuteDbDataReader(CommandBehavior behavior) +12 
    System.Data.Common.DbCommand.System.Data.IDbCommand.ExecuteReader(CommandBehavior behavior) +10 
    System.Data.Common.DbDataAdapter.FillInternal(DataSet dataset, DataTable[] datatables, Int32 startRecord, Int32 maxRecords, String srcTable, IDbCommand command, CommandBehavior behavior) +144 
    System.Data.Common.DbDataAdapter.Fill(DataSet dataSet, Int32 startRecord, Int32 maxRecords, String srcTable, IDbCommand command, CommandBehavior behavior) +319 
    System.Data.Common.DbDataAdapter.Fill(DataSet dataSet, String srcTable) +92 
    System.Web.UI.WebControls.SqlDataSourceView.ExecuteSelect(DataSourceSelectArguments arguments) +1618 
    System.Web.UI.DataSourceView.Select(DataSourceSelectArguments arguments, DataSourceViewSelectCallback callback) +21 
    System.Web.UI.WebControls.DataBoundControl.PerformSelect() +143 
    System.Web.UI.WebControls.BaseDataBoundControl.DataBind() +74 
    System.Web.UI.WebControls.GridView.DataBind() +4 
    System.Web.UI.WebControls.BaseDataBoundControl.EnsureDataBound() +66 
    System.Web.UI.WebControls.GridView.OnPreRender(EventArgs e) +26 
    System.Web.UI.Control.PreRenderRecursiveInternal() +103 
    System.Web.UI.Control.PreRenderRecursiveInternal() +175 
    System.Web.UI.Control.PreRenderRecursiveInternal() +175 
    System.Web.UI.Control.PreRenderRecursiveInternal() +175 
    System.Web.UI.Control.PreRenderRecursiveInternal() +175 
    System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint) +2496 
+1

「a」的定義在哪裏(並且此代碼看起來像SQL注入的配方) –

+0

您能打印出整個查詢嗎?重新生成導致錯誤,並把它放在這裏,所以我們可以看到你的查詢建築的輸出是什麼?另外,你在用戶輸入之間附加SQL的方式是潛在的危險 – mwan

+1

@Kirk Woll是的,它確實看起來像一些巨大的SQL注入可能發生。 – Jeremy

回答

1

你應該給我們的SQL 後的替代,但你的問題很可能是其中:

  • 你得到「Quarter.Year = aand。 。 。「因爲」a「之後缺少空格
  • 您與我猜測的值相比較的值是字符串字段(QuarterName,Course Title)周圍沒有引號
  • String.Join可能不會「和」在字符串的最開始處
+0

+1在String.Join上很不錯的拾取,完全沒有現貨那。 – Jeremy

+0

謝謝,你的觀點非常有幫助。 String.Join確實會添加「and」,但是隻有在第一個數組值被填充之後。因此,我所做的是將WHERE子句更改爲:(Quarter.Year =「+ a +」和「+ String.Join(」and「,arrFields.ToArray())+」)「; – nick

-1

當您使用的平等在SQL字符串如果列類型是數字(即long,int等),則不需要引號。

您也可以使用String.Format這將提高可讀性。這是: String.Format("Quarter.Quarter_Name = '{0}'", DDLQuarter.SelectedValue.ToString());

這裏是你的原代碼串平等固定:

if (DDLFaculty.SelectedValue != "Select") 
     { 
      arrFields.Add("Employee.Employee_ID = '" + DDLFaculty.SelectedValue + "'"); 
     } 
     if (DDLQuarter.SelectedValue != "Select") 
     { 
      arrFields.Add("Quarter.Quarter_Name = '" + DDLQuarter.SelectedValue + "'"); 
     } 
     if (DDLCourse.SelectedValue != "Select") 
     { 
      arrFields.Add("Course.Title = '" + DDLCourse.SelectedValue + "'"); 
     }