2017-08-02 107 views
0

我必須在C#中執行SQL Server查詢方法。場景是:SQL選擇條件與輸入變量

該方法正在接受變量爲string category。如果category = "Heterogeneous"值以後,我作爲選擇:

SqlCommand myCommand = con.CreateCommand(); 
if (simCategory == "Heterogeneous") 
{ 
    myCommand.CommandText = @"SELECT ProbabilityHeterogeneous FROM Graph 
    WHERE SourceID = @sourceID AND DestinationID = @destinationID"; 
} 
else if (simCategory == "Low") 
{ 
    myCommand.CommandText = @"SELECT ProbabilityLow FROM Graph 
    WHERE SourceID = @sourceID AND DestinationID = @destinationID"; 
} 
else if (simCategory == "Medium") 
{ 
    myCommand.CommandText = @"SELECT ProbabilityMedium FROM Graph 
    WHERE SourceID = @sourceID AND DestinationID = @destinationID"; 
} 
else if (simCategory == "High") 
{ 
    myCommand.CommandText = @"SELECT ProbabilityHigh FROM Graph 
    WHERE SourceID = @sourceID AND DestinationID = @destinationID"; 
} 

myCommand.Parameters.AddWithValue("@sourceID", sID); 
myCommand.Parameters.AddWithValue("@destinationID", dID); 

using (SqlDataReader myReader = myCommand.ExecuteReader()) 
{ 
    while (myReader.Read()) 
    { 
     inNeighborActivationProbability = Convert.ToDouble(myReader["Probability"]); 
    } 
    myReader.Close(); 
} 

現在,是這樣事實?

+0

你的'commandText'語句在哪兒?只需根據類別參數進行更改即可。我看不出有什麼問題。 –

+0

@JuanCarlosOropeza我們不能把'Select @Probability ...'放在'SELECT'後面嗎?當您建議更改'commandText'時,那麼每當我們需要更改查詢時,但問題是將所有這些都放在一個查詢中? – maliks

+0

沒有。您不能使用參數更改字段名稱。您需要根據類別更改您的commandText,然後添加參數並執行命令。但要小心,因爲如果使用一個外部字符串來構建查詢,則可以獲得sql注入。 Sql注入警告https://xkcd.com/327/ –

回答

0

你的代碼沒有任何(真的)錯誤。你可能認爲存在的原因是因爲你似乎重複了很多代碼,並且感覺不到'正確'或'高效'。 如果你想保留什麼領域你的C#代碼中使用的決定,那麼你可以做的事情有點更有效的是這樣的:

 string fieldName; 
     switch (simCategory) 
     { 
      case "Heterogeneous": 
       fieldName = "ProbabilityHeterogeneous"; 
       break; 

      case "Low": 
       fieldName = "ProbabilityLow"; 
       break; 

      case "Medium": 
       fieldName = "ProbabilityMedium"; 
       break; 

      case "High": 
       fieldName = "ProbabilityHigh"; 
       break; 

      default: 
       throw new ArgumentOutOfRangeException(nameof(simCategory), "Unsupported Simulation Category requested."); 
     } 

     SqlCommand myCommand = con.CreateCommand(); 
     myCommand.CommandText = string.Format("SELECT {0} as Probability FROM Graph WHERE SourceID = @sourceID AND DestinationID = @destinationID", fieldName); 
     myCommand.Parameters.AddWithValue("@sourceID", sID); 
     myCommand.Parameters.AddWithValue("@destinationID", dID); 

     using (SqlDataReader myReader = myCommand.ExecuteReader()) 
     { 
      etc... 

這應該是更容易閱讀和的情況下,保持你需要添加字段。如果由於某種原因,你寧願在SQL中做決策(例如,當你把邏輯放入一個存儲過程中,這樣你就可以擴展數據庫模型和功能,而不必升級每一個客戶端 - 機),您可以構建SQL代碼,看起來像這樣:

SELECT (CASE @parameter WHEN 'Heterogeneous' THEN ProbabilityHeterogeneous 
         WHEN 'Low'   THEN ProbabilityLow 
         WHEN 'Medium'  THEN ProbabilityMedium 
         WHEN 'High'   THEN ProbabilityHigh 
              ELSE NULL END) as Probability 
    FROM Graph 
    WHERE SourceID = @sourceID 
    AND DestinationID = @destinationID 

記住,在這種情況下,一個「錯誤」的參數值不會導致錯誤,而只是將返回NULL作爲值。

0

使用Switch更清楚。您還需要在Probabilty上使用別名。所以你可以在最後調用它,無論哪一個用戶選擇:myReader["Probability"]

最後嘗試包括一個默認選項,以防萬一。

SqlCommand myCommand = con.CreateCommand(); 

switch (simCategory) 
{ 
    case "Heterogeneous": 
     myCommand.CommandText = @"SELECT ProbabilityHeterogeneous as Probability FROM Graph 
       WHERE SourceID = @sourceID AND DestinationID = @destinationID"; 
     break; 

    case "Low": 
     myCommand.CommandText = @"SELECT ProbabilityLow as Probability FROM Graph 
       WHERE SourceID = @sourceID AND DestinationID = @destinationID"; 
     break; 

    case "Medium": 
     myCommand.CommandText = @"SELECT ProbabilityMedium as Probability FROM Graph 
       WHERE SourceID = @sourceID AND DestinationID = @destinationID"; 
     break; 

    case "High": 
     myCommand.CommandText = @"SELECT ProbabilityHigh as Probability FROM Graph 
       WHERE SourceID = @sourceID AND DestinationID = @destinationID"; 
     break; 

    default: 
      Console.WriteLine("Default case Rise ERROR?"); 
      break; 
} 

myCommand.Parameters.AddWithValue("@sourceID", sID); 
myCommand.Parameters.AddWithValue("@destinationID", dID); 

using (SqlDataReader myReader = myCommand.ExecuteReader()) 
{ 
    while (myReader.Read()) 
    { 
     inNeighborActivationProbability = Convert.ToDouble(myReader["Probability"]); 
    } 
    myReader.Close(); 
} 
0

我看你的列名,如「概率*」和由simCategory結束,所以我建議下面的代碼更清晰

記:你也需要處理,如果simCategory是空或空。

string sql = ""; 
switch (simCategory) 
{ 
case "Heterogeneous": 
case "Low": 
case "Medium": 
case "High":   
    sql=simCategory; 
    break; 
default: 
     // handle error 
    break; 
} 

SqlCommand myCommand = con.CreateCommand(); 
myCommand.CommandText = string.Format(@"SELECT Probability{0} as Probability FROM Graph WHERE SourceID = 
        @sourceID AND DestinationID = @destinationID", sql); 
myCommand.Parameters.AddWithValue("@sourceID", sID); 
myCommand.Parameters.AddWithValue("@destinationID", dID); 

using (SqlDataReader myReader = myCommand.ExecuteReader()) 
{ 
while (myReader.Read()) 
    { 
    inNeighborActivationProbability = Convert.ToDouble(myReader["Probability"]); 
    } 
    myReader.Close(); 
} 
+0

請注意,創建SQL注入攻擊的漏洞。 –

+0

@JuanCarlosOropeza你是對的,謝謝 –

+0

我編輯了代碼 –