什么是传递参数到SQL,为什么我需要它?

时间:2010-07-09 20:15:40

标签: c# asp.net sql sql-server stored-procedures

初学者:

在这个问题answer中,如何将数据插入SQL Server,他提到了传递参数而不是像我现在所拥有的字符串连接。

这对安全性来说真的有必要吗?如果是这样,究竟是什么传递参数?当我谷歌它我得到很多关于存储过程。这就是我想要的,我不知道存储过程....

如果你能指出我正确的方向,我将不胜感激。

感谢。

编辑:

好的,这就是我得到的。它似乎正确地更新了数据库,最终我将硬编码的int更改为标签的输入。请确认我是如何做到这一点不容易受到任何SQL注入或攻击。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.Security;

using System.Data;
using System.Data.Sql;
using System.Data.SqlClient;



public partial class Stats : System.Web.UI.Page
{

    public SqlDataReader DataReader;
    public SqlCommand Command;
    string queryString = ("INSERT INTO UserData (UserProfileID, ConfidenceLevel, LoveLevel, HappinessLevel) VALUES (@UID, @CL, @LL, @HL);");
    //string queryString = ("INSERT INTO UserData (UserProfileID, ConfidenceLevel, LoveLevel, HappinessLevel) VALUES ('a051fc1b-4f51-485b-a07d-0f378528974e', 2, 2, 2);"); 

    protected void Page_Load(object sender, EventArgs e)
    {
       LabelUserID.Text = Membership.GetUser().ProviderUserKey.ToString();

    }

    protected void Button1_Click(object sender, EventArgs e)
    {

        //connect to database
        MySqlConnection database = new MySqlConnection();
        database.CreateConn(); 

        //create command object
        Command = new SqlCommand(queryString, database.Connection);

        //add parameters. used to prevent sql injection
        Command.Parameters.Add("@UID", SqlDbType.UniqueIdentifier);
        Command.Parameters["@UID"].Value = Membership.GetUser().ProviderUserKey;

        Command.Parameters.Add("@CL", SqlDbType.Int);
        Command.Parameters["@CL"].Value = 9;

        Command.Parameters.Add("@LL", SqlDbType.Int);
        Command.Parameters["@LL"].Value = 9;

        Command.Parameters.Add("@HL", SqlDbType.Int);
        Command.Parameters["@HL"].Value = 9;

        Command.ExecuteNonQuery(); 


    }

}

5 个答案:

答案 0 :(得分:18)

将参数传递给SQL使您无需构建动态SQL字符串。

构建动态SQL语句是一个巨大的安全风险,因为人们可以将自己的SQL代码注入到您的应用程序中,可能会针对您的数据执行不需要的命令。

可能有一些可能的SQL注入攻击样本:

SQL Injection Attacks by Example

将参数传递给SQL语句有两种方法。一种是使用你提到的存储过程。另一种是使用参数化查询(这实际上是我更喜欢的)。

参数化查询在.NET中实际上非常简单:

using(SqlConnection conn = new SqlConnection(connString))
{
    SqlCommand command = 
        new SqlCommand("SELECT * FROM Users WHERE Username = @Username", conn);

    command.Parameters.Add(new SqlParameter("@Username", "Justin Niessner"));

    SqlDataAdapter adapter = new SqlDataAdapter(command);
    DataTable dt = new DataTable();

    adapter.Fill(dt);
}

在该示例中,参数为@Username,我们使用Parameters对象的SqlCommand集合来传递值。

答案 1 :(得分:8)

它会保护你免受小鲍比桌的伤害。

http://xkcd.com/327/

答案 2 :(得分:3)

以下是一个例子:

        SqlConnection myConn = new SqlConnection("my connection string");

        SqlCommand myCmd = new SqlCommand("myStoredProcName", myConn);

        myCmd.CommandType = CommandType.StoredProcedure;

        myCmd.Parameters.AddWithValue("@cGroupID", 0).Direction = ParameterDirection.InputOutput;
        myCmd.Parameters.AddWithValue("@gType", "C");
        myCmd.Parameters.AddWithValue("@requirement", "Y");
        myCmd.Parameters.AddWithValue("@usercode", "XX");

        myConn.Open();
        myCmd.ExecuteNonQuery();

        int covID = (int)myCmd.Parameters["@cGroupID"].Value;

使用参数是防止某些错误的好方法,并有助于停止注射矢量。它还允许OUTPUT参数,如上例所示,其中cGroupID返回一个我可以访问的值。

答案 3 :(得分:2)

简单地连接字符串的主要问题是它常常容易受到SQL注入攻击。

Google SQL注入或阅读here

答案 4 :(得分:1)

除了SQL注入等之外,参数化查询总是与SQL服务器看起来相同。最有可能的是查询执行计划将被缓存,因此如果再次发送相同的查询,它将运行得更快。如果您在循环中多次运行相同的查询,或者有许多客户端查询您的服务器,这将非常明显。