2010-05-06 7 views
7

Tôi gặp vấn đề với đoạn mã folowwing. Tôi đang chuyển một tham số (List<SqlParameter>) đến một phương thức thực hiện đoạn mã sau.SqlCommand.Parameters.AddWithValue issue: Thủ tục hoặc hàm X mong đợi tham số @Y, không được cung cấp

Khi nó thực hiện SQL Server ném một lỗi nói rằng proc mong đợi một tham số không được cung cấp. Tôi biết lỗi này và hiểu nó, và khi bước qua mã tôi có thể thấy rằng đối tượng cmdExecuteReader có một tập hợp các tham số với tên và giá trị chính xác. Điều gì có thể là vấn đề?

 public SqlDataReader ExecuteReader(string storedProcedure, List<SqlParameter> parameters = null) 
     { 
        SqlCommand cmdExecuteReader = new SqlCommand() 
        { 
         CommandType = System.Data.CommandType.Text, 
         Connection = conn, 
         CommandText = storedProcedure 
        }; 

        if (parameters != null) 
        { 
         foreach (SqlParameter param in parameters) 
         { 
          cmdExecuteReader.Parameters.AddWithValue(param.ParameterName, param.Value); 
         } 
        } 

        if (conn.State == System.Data.ConnectionState.Closed) 
         conn.Open(); 
        return cmdExecuteReader.ExecuteReader(); 
     } 

Trả lời

10

.Value đặt thành null cho bất kỳ tham số nào? Nếu vậy, chúng không được gửi đi. Hãy thử:

cmdExecuteReader.Parameters.AddWithValue(param.ParameterName, 
     param.Value ?? DBNull.Value); 

(lưu ý các null-coalescing với DBNull.Value)

Ngoài ra, lưu ý rằng AddWithValue có thể tác động truy vấn kế hoạch tái sử dụng của bạn, như (cho các chuỗi vv) nó sử dụng chiều dài của giá trị. Nếu bạn cần hiệu suất tối đa, bạn nên thiết lập tham số theo cách thủ công với các kích thước được xác định được xác định.

Cũng lưu ý rằng có khả năng một số thông số trong danh sách có thể là đầu vào-đầu ra, đầu ra hoặc kết quả. Tôi sẽ rất bị cám dỗ để thay thế cho một cái gì đó giống như hơn:

SqlParameter newParam = cmdExecuteReader.Parameters.Add(
     param.ParameterName, param.SqlDbType, param.Size); 
newParam.Value = param.Value ?? DBNull.Value; 
newParam.Direction = param.Direction; 
+0

+1. Cá nhân tôi không sử dụng AddWithValue, thích xác định rõ ràng các kiểu dữ liệu (và kích cỡ) - nếu không bạn có thể kết thúc với các giả định không chính xác (chẳng hạn như các giá trị chuỗi .NET được truyền vào như là NVARCHAR) mà tôi bị hoang tưởng về – AdaTheDev

0

tôi đã làm những thứ mà bạn đang cố gắng để làm, ở đây một số ví dụ:

public int ChangeState(int id, int stateId) 
{ 
    return DbUtil.ExecuteNonQuerySp("changeDossierState", Cs, new { id, stateId }); 
} 

public IEnumerable<Dossier> GetBy(int measuresetId, int measureId, DateTime month) 
{ 
    return DbUtil.ExecuteReaderSp<Dossier>("getDossiers", Cs, new { measuresetId, measureId, month }); 
} 

tôi khuyên bạn nên tìm kiếm here

và để tải xuống các giải pháp mẫu (trong đó có một dự án mẫu DAL bao gồm) http://valueinjecter.codeplex.com/