参数化和更新查询

时间:2014-12-12 16:33:48

标签: c# sql .net parameters

我在Visual Studio中有一个查询工作正常,但我现在需要参数化SQL查询。我不确定该怎么做。

private static void Main(string[] args)
{
    ....
    Console.WriteLine("Updating");
    string query = @"UPDATE dbo.IMAGE SET PIXEL_HEIGHT = " + Height +
                       ", PIXEL_WIDTH = " + Width +
                       ", SIZE = " + FileSize + "WHERE IMAGE_NO = " + imageNo;
    //run sql against table
    RunQuery(query);

高度,宽度,FileSize和ImageNo早先设置。

非常感谢任何帮助或指导。

这是RunQuery部分..

    public static void RunQuery(string query)
    {
        SqlConnection con = null;

        try
        {
            const string connectionString = "server=KY1-vrt-msqld1; uid=cpdba; pwd=#######; database=CommerceDB";

            con = new SqlConnection(connectionString);
            con.Open();

            SqlCommand cmd = new SqlCommand(query,con);
            int sqlcode  = cmd.ExecuteNonQuery();
        }
        catch (Exception ex)
        {
            throw;
        }

    }

3 个答案:

答案 0 :(得分:3)

要更改代码以使用参数化查询,您需要进行两项更改。

  • 首先,您的命令文本应包含参数占位符
  • 其次,RunQuery方法中的SqlCommand对象需要填充Parameter集合 使用任何参数占位符的参数...

这需要在主

中进行以下更改
private static void Main(string[] args)
{

    // Build a command text with parameters placeholders (@xxxx)
    string query = @"UPDATE dbo.IMAGE
                    SET PIXEL_HEIGHT = @Height, PIXEL_WIDTH = @Width, 
                        SIZE = @FileSize WHERE IMAGE_NO = @imageNo;";

    // Create a parameter list. Each parameter name should match the parameter 
    // placeholder in the command text and EACH parameter should be defined with
    // the appropriate SqlDbType for the underlying datatable field that will be 
    // updated..
    List<SqlParameter> pList = new List<SqlParameter>();
    pList.Add(new SqlParameter 
    {
       ParameterName = "@Height",
       SqlDbType = SqlDbType.Int,
       Value = Height
    });
    pList.Add(new SqlParameter 
    {
       ParameterName = "@Width",
       SqlDbType = SqlDbType.Int,
       Value = Width
    });
    .... and so on for the other parameter required

    // Now call you RunQuery, but pass also the parameter list
    RunQuery(query, pList);

}

// The method receives the command text and the parameters required to run the query
private static void RunQuery(string cmdText, List<Parameter> pList = null)
{
     using(SqlConnection cn = new SqlConnection(....constring....))
     using(SqlCommand cmd = new SqlCommand(cmdText, cn))
     {
         cn.Open();
         if(pList != null) cmd.Parameters.AddRange(pList.ToArray());
         cmd.ExecuteNonQuery();
     }
}

RunQuery方法中,pList变量为optional parameter。这意味着您调用RunQuery而不传递List<SqlParameter>的现有代码仍然有效,而新代码可以利用List<SqlParameter>执行更安全的参数化查询(我建议您查看现有的调用来评估Sql Injection的可能性)

修改
查看现有的RunQuery代码,我还建议查看using statement。如果该代码抛出,则连接仍然是打开的,而如果使用using语句则不会发生这种情况。

答案 1 :(得分:1)

您需要最终结果才能完成以下工作:

string query = @"UPDATE dbo.IMAGE
                  SET PIXEL_HEIGHT = @Height, PIXEL_WIDTH = @Width,SIZE = @Size
                  WHERE IMAGE_NO = @ImageNo";
using (var cn = new SqlConnection("connection string here") )
using (var cmd = new SqlCommand(query, cn))
{
    //guessing at the types. Use the exact column types from your database
    cmd.Parameters.Add("@Height", SqlDbType.Int).Value = Height;
    cmd.Parameters.Add("@Width", SqlDbType.Int).Value = Width;
    cmd.Parameters.Add("@Size", SqlDbType.Int).Value = Size;
    cmd.Parameters.Add("@ImageNo", SqlDbType.Int).Value = imageNo;

    cn.Open();
    cmd.ExecuteNonQuery();
}

要使其工作,您可能需要重新编写现有的RunQuery()方法。该方法现在的问题是无法从查询字符串中单独传递参数数据。有很多方法可以解决这个问题:例如,你可以添加一个列表或数组参数,然后迭代它。但是,我发现以下方法最有效:

public void RunQuery(string sql, Action<SqlParameterCollection> addParameters)
{
    using (var cn = new SqlConnection("Connection string here") )
    using (var cmd = new SqlCommand(sql, cn))
    {
        if (addParameters != null) addParameters(cmd.Parameters);

        cn.Open();
        cmd.ExecuteNonQuery();
    }
}

然后你就这样称呼它:

private static void Main(string[] args)
{
    //...
    Console.WriteLine("Updating");
    RunQuery(@"UPDATE dbo.IMAGE
               SET PIXEL_HEIGHT = @Height, PIXEL_WIDTH = @Width, SIZE = @Size
               WHERE IMAGE_NO = @ImageNo", p =>
             {
                  p.Add("@Height", SqlDbType.Int).Value = Height;
                  p.Add("@Width", SqlDbType.Int).Value = Width;
                  p.Add("@Size", SqlDbType.Int).Value = Size;
                  p.Add("@ImageNo", SqlDbType.Int).Value = imageNo;
             });
}

我喜欢这个,因为它将参数代码保存在sql查询字符串旁边,而不会重复创建参数集的工作。

答案 2 :(得分:1)

string UpdateSQLstring="UPDATE dbo.IMAGE
                                SET PIXEL_HEIGHT =@Height ... "
            SqlClient.SqlParameter  params[2];
            params[0] = new SqlClient.SqlParameter("@Height", SqlDbType.Int);
            params[0].Value =100;
            params[1] = new SqlClient.SqlParameter("@Width",SqlDbType.Int);
            params[1].Value = 200;
            SqlClient.SqlCommand myCMD=New SqlClient.SqlCommand(UpdateSQLstring, connection)
          myCMD.Parameters.Add(params[0]);
          myCMD.Parameters.Add(params[1]);
          myCMD.ExecuteNonQuery