2013-08-28 41 views
0

我有一個項目正在工作,我沒有創建。作爲一個整體,我對C#和ASP.NET還比較陌生。我正在面對這個SQL查詢:如何在C#中使用變量數據SQL查詢字符串

var sql = @"SELECT * FROM [database] WHERE [submitDate] >= Convert(datetime,'20130301')"; 

var sql = @"SELECT * FROM (SELECT ROW_NUMBER() OVER(ORDER BY id)AS rowNum, * FROM [webDBs].[dbo].[employeeRecognition] WHERE [submitDate] >= Convert(datetime,'20130301') 
) AS E 
WHERE rowNum >= {0} 
AND rowNum < {1}"; 

這些當然的行爲完全符合預期。然而,我需要做的是讓Convert(datetime,'20130301')位的2013部分實際上等於當前值,這樣我們就不必每隔一年更新一次這個查詢。

根據我有限的經驗,我嘗試在C#變量中進行連接,不僅沒有工作,而且在經過一些研究之後,我發現該方法可能是潛在的SQL注入開放。

我讀了一些關於參數化SQL查詢的內容,但是我看到的所有內容都讓我相信我必須首先重寫/重新思考數據如何從數據庫中提取。

有關如何完成我的目標的任何建議?

這裏就是我的工作:

protected string RecordCount() 
     { 
      EmployeeRecognitionDataContext db = new EmployeeRecognitionDataContext(); 

      var sql = @"SELECT * FROM [database] WHERE [submitDate] >= Convert(datetime,'20130301')"; 

      var query = db.ExecuteQuery<employeeRecognition>(sql); 

      //return "[{\"count\":\"" + query.Count() + "\"}]"; 
      return query.Count().ToString(); 
     } 

功能的第二var正在使用中:

protected string SelectRecords(int startIndex, int pageSize) { 

      int rowNum = startIndex + pageSize; 

      EmployeeRecognitionDataContext db = new EmployeeRecognitionDataContext(); 

      var sql = @"SELECT * FROM (
         SELECT ROW_NUMBER() OVER(ORDER BY id)AS rowNum, * FROM [database] WHERE [submitDate] >= Convert(datetime,'20130301') 
         ) AS E 
         WHERE rowNum >= {0} 
         AND rowNum < {1}"; 

      var query = db.ExecuteQuery<employeeRecognition>(sql, startIndex, rowNum); 

      List<Employee> eList = new List<Employee>(); 

      foreach (var employee in query) 
      { 
       eList.Add(new Employee { 
        value = employee.id.ToString(), 
        firstName = employee.firstName, 
        lastName = employee.lastName, 
        department = employee.department, 
        drop = employee.shortAchievement, 
        recognition = employee.longAchievement, 
        submitDate = employee.submitDate.ToString() 
       }); 

      } 

      JavaScriptSerializer serializer = new System.Web.Script.Serialization.JavaScriptSerializer(); 

      return serializer.Serialize(eList); 
     } 
+0

你有什麼問題與參數?參數是正確的方法。 (或者在SQL中完成) – SLaks

+0

問題始於我不知道如何正確地向這個特定的字符串添加參數。我發現這樣做的方法是將'Parameter.Add'顯示爲在SQL查詢只是一個字符串的特定實例中似乎不起作用的方法。 – TXChetG

回答

1

你可以只改變其生成的字符串代碼。就像是;

String.Format(@"SELECT * FROM [database] WHERE [submitDate] >= Convert(datetime,'{0}0301')", DateTime.Now.Year.ToString()); 

會使得字符串始終有當年。

String.Format的文檔可以在這裏找到http://msdn.microsoft.com/en-us/library/system.string.format.aspx

它基本上是這樣的。你打電話String.Format第一個參數是你的字符串。在該字符串中,您將格式說明符({0}是格式說明符)。 {x}的每個實例都將替換爲相應的參數。所以,你可以做這樣的事情;

string replacingThreeValues = String.Format("Replacing {0}, {1}, {2}", "one", "two", "three"); 

而這會導致replaceingThreeValues == "Replacing one, two, three"。因此,在第二個var sql = ...示例中,您已經放入了一些格式說明符,但是您沒有調用Format,也沒有傳遞任何參數來替換這些值。相反,你只需要一個字符串{0}和{1}就可以了。只有當你打電話給String.Format並傳遞適當的參數時,這些值纔會被你傳遞給它的參數所取代。

+0

感謝您的停止。當我嘗試使用此方法時,遇到以下錯誤:'非靜態字段需要對象引用...' – TXChetG

+0

@TXChetG對不起,我提出了一個編輯,應該是' DateTime.Now。年份「,我稱它爲一個靜態屬性,當它是一個實例屬性時。 – evanmcdonnal

+0

感謝您的編輯。至少不會導致構建錯誤。它聲稱在這一點上沒有返回任何記錄,這相當令人困惑,因爲如果我只是使用2013,它就可以工作。 – TXChetG

2

我不知道你的代碼的其餘部分是什麼樣的,但這裏有一個使用參數的例子。

using (SqlConnection connection = new SqlConnection("<connection string>")) 
{ 
    var cmd = connection.CreateCommand(); 
    cmd.CommandText = @"SELECT * FROM [database] WHERE [submitDate] >= @myDate"; 
    DateTime myDate = DateTime.Parse("<date string>"); 
    cmd.Parameters.AddWithValue("@myDate", myDate); 
    var reader = cmd.ExecuteReader(); 
    /* etc. */ 
} 
+0

我在原始問題中添加了更多內容,以便更好地瞭解我所面臨的問題。您的建議是我之前看到的參數化方法,但我不確定如何正確實施它。 – TXChetG

+0

現在我看到了其餘的圖片,我不認爲你真的需要參數。你將不得不重載ExecuteQuery方法來接受一個sql參數。 – Nathan

相關問題