2013-10-29 26 views
-3

我正在使用SQL Server 2008和C#前端。我試圖將C#中的SQL字符串傳遞給SQL Server,並且在我的WHERE語句中有2個字段有時可能包含NULL值。我有了這個代碼,在代碼隱藏我的網頁加載(這是將放置在DataGrid報告):是否有一個包含NULL值的LIKE運算符?

protected void Page_Load(object sender, EventArgs e) 
    { 
     SqlConnection sqlconnectionStatus = new SqlConnection(str); 
     string DDL_Value = Convert.ToString(Request.QueryString["DDL_Val"]); 
     string Val_Value = Convert.ToString(Request.QueryString["Val_Val"]); 
     string Trk_Value = Convert.ToString(Request.QueryString["Trk_Val"]); 
     string StDt_Value = Convert.ToString(Request.QueryString["StDt_Val"]); 
     string EnDt_Value = Convert.ToString(Request.QueryString["EnDt_Val"]); 

     string BTN_Value; 
     // Because the date is stored as an INT, you have to request the string and then 
     // convert it to an INT 
     string StDT_Vals = Request.QueryString["StDt_Val"].ToString(); 
     string EnDT_Vals = Request.QueryString["EnDt_Val"].ToString(); 
     string sqlquery; 

      sqlquery = "Select DISTINCT PL.PROC_NM as Agent_Name, CCM.UNIQUE_CLAIM_ID as Unique_ID, CCM.CLAIM_ID as Claim_Number, "; 
      sqlquery = sqlquery + "CCM.SOCSEC as Employee_Last_Digit, CCM.DATE_IMPORTED as Import_Date, CCM.Orig_Open_Date as Original_Review_Date, "; 
      sqlquery = sqlquery + "AGL.ACCT_GRP as Account_Name, AL.ACCT_NUM as Account_Number, CCM.CDBBEN as Benefit_Option, CCM.BENEFIT_TYPE1 as Benefit_Type1, "; 
      sqlquery = sqlquery + "CCM.BENEFIT_TYPE2 as Benefit_Type2, CCM.BENEFIT_TYPE3 as Benefit_Type3, CCM.Cmplt as Review_Validated, CCM.Vldtn_Cmmnts as Validation_Comments, "; 
      sqlquery = sqlquery + "CCM.Gtkpr_Cmmnts as Gatekeeper_Comments, TS.StatusText as Tracking_Status "; 
      sqlquery = sqlquery + "from ClosedClaims_MERGE CCM "; 
      sqlquery = sqlquery + "LEFT JOIN PROC_LIST PL ON CCM.Spare = PL.LOGIN "; 
      sqlquery = sqlquery + "LEFT JOIN ACCT_LIST AL ON AL.ACCT_NUM = CCM.CDBACC "; 
      sqlquery = sqlquery + "LEFT JOIN ACCT_GRP_LIST AGL ON AGL.ACCT_GRP_PK = AL.ACCT_GRP_FK "; 
      sqlquery = sqlquery + "LEFT JOIN TrackingStatus TS ON TS.StatusCode = CCM.TrackingStatus "; 
      sqlquery = sqlquery + "WHERE CCM.Spare LIKE '" + DDL_Value + "' AND CCM.Cmplt LIKE '" + Val_Value + "' AND CCM.TrackingStatus IN (" + Trk_Value + ") AND CCM.DATE_IMPORTED >= '" + StDt_Value + "' AND CCM.DATE_IMPORTED <= '" + EnDt_Value + "'"; 
    } 

的代碼是健全的,它工作完全正常,如果值是選擇所有報告參數。問題是CCM.Spare和CCM.Cmplt可以從下拉列表中選擇具體的值,或者可以留空。如果留空,那麼他們需要取出所有值,不管它們是否爲NULL。當我離開一個(或兩個)空白時,這是SQL失敗的地方。我試圖檢查空白和設置變量等於'%',但顯然不工作;它只會在現場有價值的情況下提取記錄。

我想用一個語句來做到這一點,如果可能的話,我會用一些If/Then/Else循環來封鎖它。

這可能嗎?

+8

[SQL注入警報](http://msdn.microsoft.com/en-us/library/ms161953%28v=sql.105%29.aspx) - 您應該**不**將您的SQL語句連接在一起 - 使用**參數化查詢**來代替以避免SQL注入 –

+4

尤其是當它直接來自用戶輸入('Request.QueryString')時。這只是要求被黑客入侵。 –

+2

並且沒有回發檢查或使用StringBuilder。這段代碼很難閱讀。 –

回答

1

試試這個,我只是包含了第一個標準的代碼。 如上所述,不要連接參數;第二個選項是做到這一點的最好辦法:

sqlquery = sqlquery + 
    "WHERE CCM.Spare " + (DDL_Value == null ? "IS NULL" : "LIKE '" + DDL_Value + "'") + " AND ...";
sqlquery = sqlquery + 
    "WHERE CCM.Spare " + (DDL_Value == null ? "IS NULL" : "LIKE @par1") + " AND ...";


Additionaly提高查詢的速度,你可以這樣做:

sqlquery = sqlquery + 
    "WHERE " + (DDL_Value != null ? "CCM.Spare LIKE @par1 AND " : "") + "...";

這將忽略CCM.Spare整個標準如果你的參數爲null。

+0

謝謝,這正是我所需要的。 –

+0

這不會返回CCM.Spare的非空值 – Jack

1

如果你想要所有可能的CCM.Spare和CCM.Cmplt值,你只需要停止謂詞。構建一個單獨的查詢(最好使用參數化查詢,如marc_s指出的),它省略了引用空白下拉值的WHERE子句。