简体   繁体   English

参数化的sql查询 - asp.net / c#

[英]parameterized sql query - asp.net / c#

So I recently learned that I should absolutely be using parametrized query's to avoid security issues such as SQL injection. 所以我最近了解到我绝对应该使用参数化查询来避免SQL注入等安全问题。 That's all fine and all, I got it working. 这一切都很好,所有,我得到了它的工作。

This code shows some of the code how I do it: 此代码显示了我如何执行的一些代码:

param1 = new SqlParameter();
param1.ParameterName = "@username";
param1.Value = username.Text;
cmd = new SqlCommand(str, sqlConn);
cmd.Parameters.Add(param1);

//and so on

But the problem is, I have over 14 variables that needs to be saved to the db, it's like a registration form. 但问题是,我有超过14个需要保存到数据库的变量,它就像一个注册表单。 And it would look really messy if I have to write those lines 14 times to parametrize each variable. 如果我必须将这些行写入14次以参数化每个变量,它看起来会非常混乱。 Is there a more dynamic way of doing this? 有没有更有活力的方法呢? Like using a for loop or something and parametrizing every variable in the loop somehow? 就像使用for循环或其他东西并以某种方式参数化循环中的每个变量一样?

使用单行SqlParameterCollection.AddWithValue方法

cmd.Parameters.AddWithValue("@username",username.Text);

或者您可能会尝试其他变体

command.Parameters.Add(new SqlParameter("Name", dogName));

Here you go... via dapper : 在这里你去......通过小巧玲珑

connextion.Execute(sql, new {
    username = username.Text,
    id = 123, // theses are all invented, obviously
    foo = "abc",
    when = DateTime.UtcNow
});

that maps to ExecuteNonQuery , but there are other methods, such as Query<T> (binds the data very efficiently by name into objects of type T per row), Query (like Query<T> , but uses dynamic ), and a few others (binding multiple grids or multiple objects, etc). 映射到ExecuteNonQuery ,但还有其他方法,如Query<T> (通过名称非常有效地将数据绑定到每行T类型的对象), Query (如Query<T> ,但使用dynamic ),以及一些其他(绑定多个网格或多个对象等)。 All ridiculously optimized (IL-level meta-programming) to be as fast as possible. 所有可笑的优化(IL级元编程)都要尽可能快。

Another technique, you can use.. 另一种技术,你可以使用..

List<SqlParameter> lstPrm = new List<SqlParameter>();

 lstPrm.Add(new SqlParameter("@pusername", usernameValue ));
 lstPrm.Add(new SqlParameter("@pID", someidValue));
 lstPrm.Add(new SqlParameter("@pPassword", passwordValue));

Add the end you can iterate to insert the parameters in your command object 添加可以迭代的结尾以在command object插入参数

Use my SqlBuilder class. 使用我的SqlBuilder类。 It lets you write paramaterized queries without ever creating a parameter, or having to worry about what its called. 它允许您在不创建参数的情况下编写参数化查询,或者不必担心其所调用的内容。 Your code will look like this... 你的代码看起来像这样......

var bldr = new SqlBuilder( myCommand );
bldr.Append("SELECT * FROM CUSTOMERS WHERE ID = ").Value(myId);
//or
bldr.Append("SELECT * FROM CUSTOMERS NAME LIKE ").FuzzyValue(myName);
myCommand.CommandText = bldr.ToString();

Your code will be shorter and much more readable. 您的代码将更短,更易读。 Compared to concatenated queries, you don't even need extra lines. 与连接查询相比,您甚至不需要额外的行。 The class you need is here... 你需要的课程在这里......

using System;
using System.Collections.Generic;
using System.Text;
using System.Data;
using System.Data.SqlClient;

public class SqlBuilder
{
private StringBuilder _rq;
private SqlCommand _cmd;
private int _seq;
public SqlBuilder(SqlCommand cmd)
{
    _rq = new StringBuilder();
    _cmd = cmd;
    _seq = 0;
}
public SqlBuilder Append(String str)
{
    _rq.Append(str);
    return this;
}
public SqlBuilder Value(Object value)
{
    string paramName = "@SqlBuilderParam" + _seq++;
    _rq.Append(paramName);
    _cmd.Parameters.AddWithValue(paramName, value);
    return this;
}
public SqlBuilder FuzzyValue(Object value)
{
    string paramName = "@SqlBuilderParam" + _seq++;
    _rq.Append("'%' + " + paramName + " + '%'");
    _cmd.Parameters.AddWithValue(paramName, value);
    return this;
}
public override string ToString()
{
    return _rq.ToString();
}
}

Better still, use my shiny new Visual Studio extension . 更好的是,使用我闪亮的新Visual Studio扩展 You declare your parameters in your sql, intact in its own file. 你在sql中声明你的参数,在你自己的文件中完整无缺。 My extension will run your query when you save your file, and will make you a wrapper class to call at runtime, and a results class to access your results, with intellisense all over da place. 我的扩展将在您保存文件时运行您的查询,并将使您成为一个在运行时调用的包装类,以及一个结果类来访问您的结果,并且智能感知到处都是。 You will see your sql parameters as arguments to the Execute() methods of the wrapper class. 您将看到您的sql参数作为包装类的Execute()方法的参数。 You will never have to write another line of parameter code in C#, or reader code, or cmd, or even connection (unless you want to manage that yourself). 您永远不必在C#,读者代码或cmd甚至连接中编写另一行参数代码(除非您想自己管理)。 Gone gone gone :-) 已经走了:-)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM