2009-03-17 29 views
15

Tôi có đoạn code dưới đây (Tôi đã bao gồm những gì tôi tin là tất cả các phần có liên quan):tham số truy vấn cho MySQL với C#

private String readCommand = "SELECT LEVEL FROM USERS WHERE VAL_1 = ? AND [email protected] = ?;"; 
public bool read(string id) 
{ 
    level = -1; 
    MySqlCommand m = new MySqlCommand(readCommand); 
    m.Parameters.Add(new MySqlParameter("", val1)); 
    m.Parameters.Add(new MySqlParameter("", val2)); 
    MySqlDataReader r = m.ExecuteReader(); 
    if (r.HasRows) 
     level = Convert.ToInt32(r.GetValue(0).ToString()); 
    r.Close(); 
    return true; 
} 

Khi tôi chạy này, tôi nhận được một IndexOutOfBoundsException về việc bổ sung các tham số đầu tiên. Tôi đã làm gì sai?

Trả lời

28

Hãy thử điều này thay vì:

private String readCommand = "SELECT LEVEL FROM USERS WHERE VAL_1 = @param_val_1 AND VAL_2 = @param_val_2;"; 
public bool read(string id) 
{ 
    level = -1; 
    MySqlCommand m = new MySqlCommand(readCommand); 
    m.Parameters.AddWithValue("@param_val_1", val1); 
    m.Parameters.AddWithValue("@param_val_2", val2); 
    level = Convert.ToInt32(m.ExecuteScalar()); 
    return true; 
} 
+0

cảm ơn, tôi đoán tôi phải đặt tên các tham số của tôi. Oh well. Có thể tệ hơn, tôi cho là vậy. – Elie

+0

Ồ, và @ đã làm việc tốt. – Elie

+1

Cảm ơn bạn đã cho tôi biết, đó là điều tốt để biết nó hoạt động – Chris

3

Bạn cần phải sử dụng tên tham số trong truy vấn của bạn. Ví dụ .:

String readCommand = "SELECT LEVEL FROM USERS WHERE VAL_1 = ?param1 AND VAL_2 = ?param2"; 

Sau đó, vượt qua các tên tham số khi bạn nhanh chóng đối tượng MySqlParameter bạn như vậy:

m.Parameters.Add(new MySqlParameter("param1", val1)); 
+0

Làm params mysql bắt đầu bằng '?' , trái ngược với '@' như trong máy chủ sql? Tôi nghĩ họ sẽ giống nhau. Hấp dẫn! – Chris

+0

Nhận xét của người dùng trong http://dev.mysql.com/doc/refman/5.0/en/connector-net-examples-mysqlcommand.html nói như vậy. –

+0

@ cũng hoạt động tốt. – Elie

1

Tôi không nghĩ rằng các lớp MySql.Data hỗ trợ thông số tên. Nếu bạn muốn sử dụng chúng, bạn có thể truy cập vào MySql db thông qua trình điều khiển Odbc, chúng hỗ trợ điều này.

Bạn sẽ cần phải đặt tên các tham số trong truy vấn của bạn: "?"

"SELECT LEVEL FROM USERS WHERE VAL_1 = @val1 AND VAL_2 = @val2;" 

tôi đã chọn chỉ số param "@", nhưng các phiên bản gần đây của hỗ trợ MySql.Data cả "@" và .

Sau đó cập nhật hàm tạo param của bạn để chuyển vào tên param chính xác (bạn không cần phải bao gồm chỉ báo param ở đây, mặc dù nó không tạo ra bất kỳ sự khác biệt nào nếu bạn làm).

m.Parameters.Add(new MySqlParameter("val1", val1)); 

PS. Bạn có thể biết điều này đã được, hoặc nó đã được bỏ qua trong đoạn mã, nhưng tôi nghĩ rằng bạn quên gọi Đọc trên ví dụ của bạn về ExecuteReader.

+0

Tôi thực sự đã quên mã của tôi, và tìm thấy nó ngay sau khi con đường thực hiện đạt đến đó.Tôi đang sắp xếp lại một loạt các truy vấn cũ, và một số mã đang được di chuyển xung quanh, đó là lỗi dễ bị xâm nhập và chính nó. Cảm ơn đã giúp đỡ! – Elie

6
protected void Login1_Authenticate(object sender, AuthenticateEventArgs e) 
{ 
    MySqlConnection con = new MySqlConnection("server=localhost;User Id=root;database=result;password=1234"); 
    con.Open(); 

    MySqlCommand cmd = new MySqlCommand("Select * from users where username=?username and password=?password", con); 
    cmd.Parameters.Add(new MySqlParameter("username", this.Login1.UserName)); 
    cmd.Parameters.Add(new MySqlParameter("password", this.Login1.Password)); 

    MySqlDataReader dr = cmd.ExecuteReader(); 
    if (dr.HasRows ==true) 
    { 
     e.Authenticated = true; 
    } 
} 
2
m.Parameters.AddWithValue("parameter",value) 

sẽ là lựa chọn tốt hơn cho truy vấn parametrized.

0

Nếu bạn muốn thực hiện sql nhiều lần, sau đó bạn nên sử dụng theo cách này:

conn.Open(); 
cmd.Connection = conn; 

cmd.CommandText = "INSERT INTO myTable VALUES(NULL, @number, @text)"; 
cmd.Prepare(); 

cmd.Parameters.AddWithValue("@number", 1); 
cmd.Parameters.AddWithValue("@text", "One"); 

for (int i=1; i <= 1000; i++) 
{ 
    cmd.Parameters["@number"].Value = i; 
    cmd.Parameters["@text"].Value = "A string value"; 

    cmd.ExecuteNonQuery(); 
} 

Lần đầu tiên là không có "ExecuteNonQuery" chỉ cần thêm các thông số với các giá trị giả, sau đó bên trong vòng lặp bạn thêm giá trị thực.

Xem liên kết này: https://dev.mysql.com/doc/connector-net/en/connector-net-programming-prepared-preparing.html

Các vấn đề liên quan