05 июн. 2012 г., 17:57 отmarcmiller2007

Параметризация SQL-запроса

Много сообщений о параметрах в SQL с C #, но я все еще что-то упускаю. Я не получаю сообщение об ошибке, но данные не вставлены. Чего не хватает? У меня есть текстовые поля с именем fname, lname, адрес, город, штат и почтовый индекс.

 private void enter_button_Click(object sender, EventArgs e)
 {
    string first, last, addy, city1, stat, zippy;
    first = fname.Text; 
    SqlParameter firstparam;
    firstparam = new SqlParameter();
    firstparam.ParameterName = "@first";
    firstparam.Value = first;
    last = lname.Text;
    SqlParameter lastparam;
    lastparam = new SqlParameter();
    lastparam.ParameterName = "@last";
    lastparam.Value = last;
    addy = address.Text;
    SqlParameter addressparam;
    addressparam = new SqlParameter();
    addressparam.ParameterName = "@addy";
    addressparam.Value = addy;
    city1 = city.Text;
    SqlParameter cityparam;
    cityparam = new SqlParameter();
    cityparam.ParameterName = "@city1";
    cityparam.Value = city1;
    stat = state.Text;
    SqlParameter stateparam;
    stateparam = new SqlParameter();
    stateparam.ParameterName = "@stat";
    stateparam.Value = stat;
    zippy = zip.Text;
    SqlParameter zipparam;
    zipparam = new SqlParameter();
    zipparam.ParameterName = "@zippy";
    zipparam.Value = zippy;

    try
    {
        Validate(fname);
        Validate(lname);
        Validate(city);
        Validate(state);
    }
    catch (Exception ex)
    {
        throw new Exception(ex.ToString(), ex);
    }

    try
    {
        exValidate(address);
    }
    catch (Exception ex1)
    {
        throw new Exception(ex1.ToString(), ex1);
    }

    try
    {
        numValidate(zip);
    }
    catch (Exception ex2)
    {
        throw new Exception(ex2.ToString(), ex2);
    }


    string connection = "Data Source=TX-MANAGER;Initial Catalog=Contacts;Integrated Security=True";
    var sqlstring = string.Format("INSERT INTO Contacts ([First] ,[Last] ,[Address] ,[City] ,[State],[ZIP]) VALUES {0}, {1}, {2}, {3}, {4}, {5})", @first, @last, @addy, @city1, @stat, @zippy);
    SqlConnection conn = new SqlConnection(connection);
    SqlCommand comm = new SqlCommand();
    comm.CommandText = sqlstring;
    try
    {
        conn.Open();
        //SqlTransaction trans = conn.BeginTransaction();
        //comm.Transaction = trans;
        comm.Parameters.Add("@first", SqlDbType.Text);
        comm.Parameters.Add("@last", SqlDbType.Text);
        comm.Parameters.Add("@addy", SqlDbType.Text);
        comm.Parameters.Add("@city1", SqlDbType.Text);
        comm.Parameters.Add("@stat", SqlDbType.Text);
        comm.Parameters.Add("@zippy", SqlDbType.SmallInt);
    }
    catch (Exception commex)
    {
        throw new Exception(commex.ToString(), commex);
    }
    conn.Close();
}

Так что я изменился на это и до сих пор ничего не происходит

     string connection = "Data Source=TX-MANAGER;Initial Catalog=Contacts;Integrated Security=True";
        var sqlstring = string.Format("INSERT INTO Contacts ([First] ,[Last] ,[Address] ,[City] ,[State],[ZIP]) VALUES {0}, {1}, {2}, {3}, {4}, {5})", @first, @last, @addy, @city1, @stat, @zippy);
        SqlConnection conn = new SqlConnection(connection);
        SqlCommand comm = conn.CreateCommand();
        comm.CommandText = sqlstring;
        try
        {
            conn.Open();
            //SqlTransaction trans = conn.BeginTransaction();
            //comm.Transaction = trans;
            comm.Parameters.AddWithValue("@first", first);
            comm.Parameters.AddWithValue("@last", last);
            comm.Parameters.AddWithValue("@addy", addy);
            comm.Parameters.AddWithValue("@city1", city1);
            comm.Parameters.AddWithValue("@stat", stat);
            comm.Parameters.AddWithValue("@zippy", zippy);
            comm.ExecuteNonQuery();

Ответы на вопрос(0)

05 июн. 2012 г., 16:18 отabatishchev

Это будет намного короче:

using (SqlConnection connection = new SqlConnection(connectionString))
using (SqlCommand command = connection.CreateCommand())
{
    command.CommandText = "INSERT INTO Contacts ([First], [Last], [Address], [City], [State], [ZIP]) VALUES (@first, @last, @address, @city, @state, @zip)";

    command.Parameters.AddWithValue("@first", first);
    // or
    // command.Parameters.Add("@first", SqlDbType.Type).Value = first;
    // ...

    connection.Open();
    command.ExecuteNonQuery();
}

Но прежде всего вот что вы пропустили:

comm.Parameters.Add(firstparam);
// instead of
// comm.Parameters.Add("@first", SqlDbType.Text);

а также

command.ExecuteNonQuery();
05 июн. 2012 г., 16:19 отGarethD

Во-первых, вы не выполняете команду, вам нужно позвонитьcomm.ExecuteNonQuery();во-вторых, ваша строка SQL будет неправильной. Эта строка:

var sqlstring = string.Format("INSERT INTO Contacts ([First] ,[Last] ,[Address] ,[City],
[State],[ZIP]) VALUES {0}, {1}, {2}, {3}, {4}, {5})", @first, @last, @addy, @city1, 
@stat, @zippy)

Может быть просто:

var sqlstring = "INSERT INTO Contacts ([First] ,[Last] ,[Address] ,[City] ,[State],[ZIP]) 
                 VALUES (@first, @last, @addy, @city1, @stat, @zippy)";

В-третьих, вы фактически не добавляете свои параметры в вашу команду. Вы создаете параметр следующим образом:

SqlParameter zipparam;
zipparam = new SqlParameter();
zipparam.ParameterName = "@zippy";
zipparam.Value = zippy;

Но вы добавляете это:

comm.Parameters.Add("@zippy", SqlDbType.SmallInt);

без ссылки наzipparam, Это означает, что значениеzippy фактически никогда не добавляется в команду. Вы можете сделать все это в одну строку, используя:

comm.Parameters.Add(new SqlParameter(@Zippy, SqlDbType.SmallInt)).Value = zippy;
06 июн. 2012 г., 18:13 отFilip De Vos

Ключевые вопросы в предоставленном образце:

The definition of the sqlstring should have the parameter definitions in the string The Call Stack is being reset when the error is thrown by creating a new error object The SqlConnection and SqlCommand object are not begin disposed correctly (for example, the conn.Close() call is not part of the Finally section of the exception handler. The Value of the SqlParameters are not being set The Execute xx method on the SqlCommand object is not begin called String Values are stored in a varchar type, not Text. Text is the deprecated SQL Server datatype to store blob.

Я бы переформулировал код следующим образом:

     private void enter_button_Click(object sender, EventArgs e)
     {
        var first = fname.Text; 
        var last = lname.Text;
        var addy = address.Text;
        var city1 = city.Text;
        var stat = state.Text;
        var zippy = zip.Text;

        Validate(fname);
        Validate(lname);
        Validate(city);
        Validate(state);
        exValidate(address);
        numValidate(zip);

        using (var conn = new SqlConnection("Data Source=TX-MANAGER;Initial Catalog=Contacts;Integrated Security=True"))
        using (var cmd = new SqlCommand(@"INSERT INTO Contacts ([First], [Last], [Address], [City], [State], [ZIP]) VALUES (@first, @last, @addy, @city1, @stat, @zippy)", conn))
        {
            cmd.Parameters.AddRange(
                new[]
                    {
                        new SqlParameter(@"first", SqlDbType.VarChar).Value = first,
                        new SqlParameter(@"last", SqlDbType.VarChar).Value = last,
                        new SqlParameter(@"addy", SqlDbType.VarChar).Value = addy,
                        new SqlParameter(@"city1", SqlDbType.VarChar).Value = city1,
                        new SqlParameter(@"state", SqlDbType.VarChar).Value = stat,
                        new SqlParameter(@"zippy", SqlDbType.SmallInt).Value = zippy
                    });
            conn.Open();
            cmd.ExecuteNonQuery();
        }
    }

Note: I prefer supplying the datatype of parameters since SqlCE does not always work correctly when no type is supplied.

05 июн. 2012 г., 16:05 отJohn Gathogo

Есть много способов сделать это. Один из способов - заменить строки в блоке try на:

comm.Parameters.AddWithValue("@first", first);
comm.Parameters.AddWithValue("@last", last);
comm.Parameters.AddWithValue("@addy", addy);
comm.Parameters.AddWithValue("@city1", city1);
comm.Parameters.AddWithValue("@stat", stat);
comm.Parameters.AddWithValue("@zippy", zippy);

Если вы делаете это, вам не нужно всеSqlParameter инициализация

И вам, очевидно, нужно выполнить команду:

comm.ExecuteNonQuery();
05 июн. 2012 г., 16:31 отThomas Levesque

Вы забыли выполнить команду;)

РЕДАКТИРОВАТЬ: вы также не использовали параметры, которые вы создали в начале метода.

    ...
    try
    {
        conn.Open();
        //SqlTransaction trans = conn.BeginTransaction();
        //comm.Transaction = trans;
        comm.Parameters.Add(firstparam);
        comm.Parameters.Add(lastparam);
        comm.Parameters.Add(addressparam);
        comm.Parameters.Add(cityparam);
        comm.Parameters.Add(stateparam);
        comm.Parameters.Add(zipparam);

        // This is what you forgot:
        comm.ExecuteNonQuery();
    }
    ...

Кстати, не делайте таких вещей:

    catch (Exception ex1)
    {
        throw new Exception(ex1.ToString(), ex1);
    }

Это бесполезно, оно просто добавляет новый уровень исключений, не добавляя ничего полезного. Просто позвольте исключению пузыриться в стеке, пока оно не достигнет блока catch, который на самом деле делает что-то полезное.

ВАШ ОТВЕТ НА ВОПРОС