用于目录扩展存储过程的名称的开头,如 xp_cmdshell。
  注:验证输入是被常用和联想到的,但是个人感觉这种方式不但代码显得肥胖,而且效率不是很好
  2.使用类型安全的 SQL 参数
  SQL Server 中的 Parameters 集合提供了类型检查和长度验证。如果使用 Parameters 集合,则输入将被视为文字值而不是可执行代码。使用 Parameters 集合的另一个好处是可以强制执行类型和长度检查。范围以外的值将触发异常。以下代码段显示了如何使用 Parameters 集合:
  1 SqlDataAdapter myCommand = new SqlDataAdapter("AuthorLogin", conn);
  2 myCommand.SelectCommand.CommandType = CommandType.StoredProcedure;
  3 SqlParameter parm = myCommand.SelectCommand.Parameters.Add("@au_id",
  4      SqlDbType.VarChar, 11);
  5 parm.Value = Login.Text;
  在此示例中,@au_id 参数被视为文字值而不是可执行代码。将对此值进行类型和长度检查。如果 @au_id 值不符合指定的类型和长度约束,则将引发异常。
  存储过程如果使用未筛选的输入,则可能容易受 SQL Injection 攻击。例如,以下代码容易受到攻击:
  SqlDataAdapter myCommand = new SqlDataAdapter("LoginStoredProcedure '" + Login.Text + "'", conn);
  如果使用存储过程,则应使用参数作为存储过程的输入。
  注:在鄙人现在的项目中,这种方法应用为广泛
  3.在动态 SQL 中使用参数集合
  如果不能使用存储过程,您仍可使用参数,如以下代码示例所示:
  1 SqlDataAdapter myCommand = new SqlDataAdapter(
  2 "SELECT au_lname, au_fname FROM Authors WHERE au_id = @au_id", conn);
  3 SQLParameter parm = myCommand.SelectCommand.Parameters.Add("@au_id",
  4  SqlDbType.VarChar, 11);
  5 Parm.Value = Login.Text;
  注:和第二种雷同,这种方法是为了补充方法2存在,因为往往在很多时候业务简单不需要用proc的时候,可以用这种方法
  4.筛选输入
  筛选输入可以删除转义符,这也可能有助于防止 SQL 注入。但由于可引起问题的字符数量很大,因此这并不是一种可靠的防护方法。以下示例可搜索字符串分隔符。
  1 private string SafeSqlLiteral(string inputSQL)
  2 {
  3   return inputSQL.Replace("'", "''");
  4 }
  注:Filtering Input有种类似方法1
  5.LIKE 子句
  请注意,如果要使用 LIKE 子句,还必须对通配符字符进行转义:
  1
  2 s = s.Replace("[", "[[]");
  3 s = s.Replace("%", "[%]");
  4 s = s.Replace("_", "[_]");
  注:针对like子句,在使用时的效率这里不多说了,总之要慎用了。
  以上所有方法及其注释高亮显示部分,均为本人愚见,如果对方法有补充或者对高亮部分有不同意见的,欢迎大家给出意见,共同进步.