2016-08-18 51 views
1

我將一長串employeeIds傳遞給employeeIdlist,然後將它們分成一個List。使用這個列表,我將參數添加到我的查詢中。 我收到以下錯誤必須在Select命令中聲明標量變量

{「必須聲明標量變量\」 @僱員\「」}

public List<versionInfo> GetVersion(string employeeIdlist) 
{ 
    DbHelper helper = new DbHelper(); 
    List<versionInfo> empVerInfo = new List<versionInfo>(); 

    using (SqlConnection conn = new SqlConnection(connString)) 
    {    
     conn.Open(); 
     using (SqlCommand getVersion = new SqlCommand()) 
     { 
      getVersion.Connection = conn; 
      getVersion.CommandText = @"SELECT EmployeeId,Version 
               FROM [dbo].[EmployeeVersion] 
               WHERE EmployeeId in (@EmployeeId)"; 

      getVersion.CommandType = CommandType.Text; 
      List<int> empIds = employeeIdlist.Split(',').Select(int.Parse).ToList(); 
      StringBuilder sb = new StringBuilder(); 
      int i = 0; 
      foreach (var emp in empIds) 
      { 
       // IN clause 
       sb.Append("@EmployeeId" + i.ToString() + ","); 
       // parameter 
       getVersion.Parameters.AddWithValue("@EmployeeId" + i.ToString(), emp); 
       i++; 
      } 

      // getVersion.Parameters.AddWithValue("@EmployeeId", employeeIdlist); 
      SqlDataReader rdr = getVersion.ExecuteReader(); 
      while (rdr.Read()) 
      { 
       versionInfo vi = new versionInfo(); 
       vi.employeeId = helper.GetDb<int>(rdr, "EmployeeId"); 
       vi.version = helper.GetDb<decimal>(rdr, "Version"); 
       empVerInfo.Add(vi);      
      } 
      rdr.Close(); 
     } 
     conn.Close(); 
    } 
    return empVerInfo; 
} 
+1

您正在添加多個參數,將您的AddWithValue保留在循環中;使用String.Join連接列表並最終只添加一個參數 – techspider

+0

我建議將sql移入存儲過程並聲明名爲'@ EmployeeId'的輸入參數,並且您有一個EmployeeId列表我還會創建一個類型並傳遞在列表中讓數據庫處理IN子句你是否熟悉在sql server中創建用戶類型..? – MethodMan

回答

5

的IN

getVersion.CommandText = @"SELECT EmployeeId,Version 
          FROM [dbo].[EmployeeVersion] 
          WHERE EmployeeId in ("; 

後刪除文本,然後在foreach可以建立的參數和文本的完整列表

foreach (var emp in empIds) 
{ 
    sb.Append("@EmployeeId" + i.ToString() + ","); 
    getVersion.Parameters.AddWithValue("@EmployeeId" + i.ToString(), emp); 
    i++; 
} 

退出循環後,從StringBuilder的刪除最後一個逗號

sb.Length--; 

最後,完成附加StringBuilder內容的命令文本,並且不要忘記IN子句的右括號。

getVersion.CommandText += sb.ToString() + ")"; 

現在可以運行使用正確的IN子句的命令和參數

+0

這很好。萬分感謝。 –

+0

太棒了。它也適用於我的問題 – Muj

0

在SELECT語句必須聲明的價值你變量。我已經把它變成了一個整數。如果它是一個文本值,那麼你可以使用varchar(25)。

@"DECLARE @EmployeeId INT 

SELECT EmployeeId,Version 
FROM [dbo].[EmployeeVersion] 
WHERE EmployeeId in (@EmployeeId)"; 
+0

OP正在嘗試在員工列表中進行搜索。請參閱'empIds'變量。 –

1

如果失敗了,因爲你的查詢字符串,有一個參數名爲@EmployeeID和您的Command對象有不同名稱的許多參數的匹配列表(「@ EmployeeId1」不等於「@EmployeeId」)

看起來你似乎試圖申請this的方法,這是一個好主意。

您是兩條線走得到它的工作:

添加此行:

sb.Lenght--; 
getVersion.CommandText = getVersion.CommandText.Replace("@EmployeeId",sb.ToString()) 

之前:

SqlDataReader rdr = getVersion.ExecuteReader(); 

這樣做,讓您的參數將匹配後@ sql字符串中存在的參數。

1

這只是另一種選擇。使用堆棧溢出中使用的Dapper ORM,可以在3行代碼中實現相同的結果。

您可以通過NuGet下載。

public class VersionInfo 
{ 
    public int EmployeeId { get; set; } 
    public decimal Version { get; set; } 
} 

class Program 
{ 
    public static string connString = "..."; 

    static void Main(string[] args) 
    { 
     var result = GetVersion(new List<int> {1, 2}); 
     Console.ReadLine(); 
    } 

    public static List<VersionInfo> GetVersion(IList<int> employeeIds) 
    { 
     using (IDbConnection conn = new SqlConnection(connString)) 
     { 
      conn.Open(); 
      var entities = conn.Query<VersionInfo>(
       @"SELECT EmployeeId, Version from EmployeeVersion WHERE EmployeeId IN @EmployeeIds", 
       new {EmployeeIds = employeeIds}); 

      return entities.ToList(); 
     } 
    } 
}