C# 参数化和更新查询

C# 参数化和更新查询,c#,sql,.net,parameters,C#,Sql,.net,Parameters,我在VisualStudio中有一个查询可以正常工作,但是我现在需要参数化SQL查询。我不知道该怎么做 private static void Main(string[] args) { .... Console.WriteLine("Updating"); string query = @"UPDATE dbo.IMAGE SET PIXEL_HEIGHT = " + Height + ", PIXEL_WIDTH = "

我在VisualStudio中有一个查询可以正常工作,但是我现在需要参数化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);
高度、宽度、文件大小和图像编号都是在前面设置的

任何帮助或指导都将不胜感激

这是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;
        }

    }

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

  • 首先,命令文本应该包含参数占位符
  • 其次,RunQuery方法中的SqlCommand对象需要填充参数集合 使用参数作为任何参数占位符
这需要在主目录中进行以下更改

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();
     }
}
private static void Main(字符串[]args)
{
//使用参数占位符(@xxxx)生成命令文本
字符串查询=@“更新dbo.IMAGE”
设置像素高度=@HEIGHT,像素宽度=@WIDTH,
SIZE=@FileSize,其中IMAGE_NO=@imageNo;“;
//创建参数列表。每个参数名称应与参数匹配
//命令文本中的占位符和每个参数都应使用
//将显示的基础datatable字段的适当SqlDbType
//更新。。
List pList=新列表();
添加(新的SqlParameter
{
ParameterName=“@Height”,
SqlDbType=SqlDbType.Int,
值=高度
});
添加(新的SqlParameter
{
ParameterName=“@Width”,
SqlDbType=SqlDbType.Int,
值=宽度
});
..等其他所需参数
//现在调用RunQuery,但还要传递参数列表
RunQuery(query,pList);
}
//该方法接收运行查询所需的命令文本和参数
私有静态void RunQuery(字符串cmdText,列表pList=null)
{
正在使用(SqlConnection cn=新的SqlConnection(..正在分析…)
使用(SqlCommand cmd=newsqlcommand(cmdText,cn))
{
cn.Open();
if(pList!=null)cmd.Parameters.AddRange(pList.ToArray());
cmd.ExecuteNonQuery();
}
}
RunQuery
方法中,
pList
变量是一个变量。这意味着在不传递
List
的情况下调用RunQuery的现有代码仍然可以工作,而新代码可以利用
List
执行更安全的参数化查询(我建议查看现有调用以评估Sql注入的可能性)

编辑

查看您现有的RunQuery代码,我还建议您检查一下。如果该代码抛出,则连接仍处于打开状态,而如果使用using语句,则不会发生这种情况。

要将代码更改为使用参数化查询,需要进行两次更改

  • 首先,命令文本应该包含参数占位符
  • 其次,RunQuery方法中的SqlCommand对象需要填充参数集合 使用参数作为任何参数占位符
这需要在主目录中进行以下更改

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();
     }
}
private static void Main(字符串[]args)
{
//使用参数占位符(@xxxx)生成命令文本
字符串查询=@“更新dbo.IMAGE”
设置像素高度=@HEIGHT,像素宽度=@WIDTH,
SIZE=@FileSize,其中IMAGE_NO=@imageNo;“;
//创建参数列表。每个参数名称应与参数匹配
//命令文本中的占位符和每个参数都应使用
//将显示的基础datatable字段的适当SqlDbType
//更新。。
List pList=新列表();
添加(新的SqlParameter
{
ParameterName=“@Height”,
SqlDbType=SqlDbType.Int,
值=高度
});
添加(新的SqlParameter
{
ParameterName=“@Width”,
SqlDbType=SqlDbType.Int,
值=宽度
});
..等其他所需参数
//现在调用RunQuery,但还要传递参数列表
RunQuery(query,pList);
}
//该方法接收运行查询所需的命令文本和参数
私有静态void RunQuery(字符串cmdText,列表pList=null)
{
正在使用(SqlConnection cn=新的SqlConnection(..正在分析…)
使用(SqlCommand cmd=newsqlcommand(cmdText,cn))
{
cn.Open();
if(pList!=null)cmd.Parameters.AddRange(pList.ToArray());
cmd.ExecuteNonQuery();
}
}
RunQuery
方法中,
pList
变量是一个变量。这意味着在不传递
List
的情况下调用RunQuery的现有代码仍然可以工作,而新代码可以利用
List
执行更安全的参数化查询(我建议查看现有调用以评估Sql注入的可能性)

编辑

查看您现有的RunQuery代码,我还建议您检查一下。如果该代码抛出,则连接仍处于打开状态,而如果使用using语句,则不会发生这种情况。

您需要最终结果来执行以下操作:

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();
}
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;
             });
}
为了实现这一点,您可能需要重新编写现有的
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();
    }
}

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

您需要最终结果来执行以下操作:

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();
}
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;
             });
}
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
为了实现这一点,您可能需要重新编写现有的
RunQuery()
方法。目前这种方法的问题是