C#编程:Parameters的Add方法的参数问题。

2024-11-01 16:05:20
推荐回答(3个)
回答1:

在c#中执行sql语句时传递参数的小经验

 1、直接写入法:

      例如:     

int Id =1;
             string Name="lui";
             cmd.CommandText="insert into TUserLogin values("+Id+",'"+Name+"')";

        因为Id是数值,所以在传递的时候只需要在sql字符串中用"+Id+"即可实现,而   Name是字符串,所以在传递的时候还需要在"+Name+"两边各加一个单引号(')来 实现; 

2、给命令对象添加参数法:

     例如:

int Id =1;
            string Name="lui";
            cmd.CommandText="insert into TUserLogin values(@Id,@Name)";

          //上条语句中直接在sql语句中写添加的参数名,不论参数类型都是如此.

           SqlParameter  para=new SqlParameter("@Id",SqlDbType.int,4);//生成一个名字为@Id的参数,必须以@开头表示是添加的参数,并设置其类型长度,类型长度与数据库中对应字段相同

   para.Value=Id;//给参数赋值
           cmd.Parameters.Add(para);//必须把参数变量添加到命令对象中去。
           //以下类似
           para=new SqlParameter("@Name",SqlDbType.VarChar,16);
           para.Value=Name;
           com.Parameters.Add(para);

        ...然后就可以执行数据库操作了。


 SqlParameter用法

SqlParameter[] parameters = { new SqlParameter("@a", "a1"), new SqlParameter("@b", "b1") };
            string strReturn = "";
            StringBuilder strBulResult = new StringBuilder();
            foreach (SqlParameter parameter in parameters)
            {
                strBulResult.Append(parameter.ParameterName);
                strBulResult.Append(":");
                strBulResult.Append(parameter.SqlValue); 
                strBulResult.Append("\n"); 
            }
       strReturn = strBulResult.ToString();

SqlParameter用法

 

  关于Sql注入的基本概念,相信不需多说,大家都清楚,经典的注入语句是' or 1=1--

单引号而截断字符串,“or 1=1”的永真式的出现使得表的一些信息被暴露出来,如果sql语句是select * from 的话,可能你整个表的信息都会被读取到,更严重的是,如果恶意使用都使用drop命令,那么可能你的整个数据库得全线崩溃。 

当然,现在重点不是讲sql注入的害处,而是说说如何最大限度的避免注入问题。

 sql注入的存在在最大危害,是sql的执行语句没有和控制语句分开,我们想要select一些东西,但用户可能拼出' or 1=1甚至再加上delete/update/drop,后来是属于控制语句了,所以要避免sql的注入,就必须把查询语句与控制语句分开。


SqlParameter给我们提供了一个很好的类,有了它,我们可以不现拼接字符串,也可以不再担心单引号带来的惨剧,因为,这一切会有人来为我们完成的。

 

简单的给个示例

传统的查询语句的sql可能为

string sql="select * from users where user_id='"+Request.QueryString["uid"]+"'";

很显然,我们在这里拼接了字符串,这就给sql注入留下了可乘之机。

现在,我们要改写这样的语句,使用SqlParameter来做 

SqlCommand SqlCmd = new SqlCommand(sql, SqlConn);
SqlParameter _userid = new SqlParameter("uid", SqlDbType.Int);
_userid.Value = Request.QueryString["u_id"];
SqlCmd.Parameters.Add(_userid);

 

这样,我们可以保证外接参数能被正确的转换,单引号这些危险的字符也会转义了,不会再对库造成威胁。

当然,这仅是一个示例而已,在真实的情况下,可能你还要对 Request.QueryString["u_id"]进行必要的检测与分析,这样才安全

 

所以,使用参数化的sql语句,是一种很好的做法

Dim sql As StringBuilder = New StringBuilder()
            sql.Append("")
            sql.Append("SELECT * FROM test")
            sql.Append(" WHERE  a= @p1 ")           
 
            Dim command As SqlCommand    =    dac.CreateCommand(sql.ToString())  'dac为自己写的类
            Dim param As SqlParameter = New SqlParameter()
            param .ParameterName = "@p1"
            param .SqlDbType = SqlDbType.NVarChar
            param .Value = b       'b为该函数的参数(ByVal b as String)
            command .Parameters.Add(param)
            Dim reader As SqlDataReader = command.ExecuteReader()

SqlParameter 构造函数

 

SqlParameter 构造函数 (String, SqlDbType, Int32, ParameterDirection, Byte, Byte, String, DataRowVersion, Boolean, Object, String, String, String)

初始化 SqlParameter 类的一个新实例,该类使用参数名、参数的类型、参数的长度、方向、精度、小数位数、源列名称、DataRowVersion 值之一、用于源列映射的布尔值、SqlParameter 的值、此 XML 实例的架构集合所在的数据库的名称、此 XML 实例的架构集合所在的关系架构以及此参数的架构集合的名称。

命名空间: System.Data.SqlClient

程序集: System.Data(在 system.data.dll 中)

C#

public SqlParameter (
    string parameterName,
    SqlDbType dbType,
    int size,
    ParameterDirection direction,
    byte precision,
    byte scale,
    string sourceColumn,
    DataRowVersion sourceVersion,
    bool sourceColumnNullMapping,
    Object value,
    string xmlSchemaCollectionDatabase,
    string xmlSchemaCollectionOwningSchema,
    string xmlSchemaCollectionName
)


参数

parameterName

要映射的参数的名称。

dbType

SqlDbType 值之一。 

size

参数的长度。

direction

ParameterDirection 值之一。

precision

要将 Value 解析为的小数点左右两侧的总位数。 

scale

要将 Value 解析为的总小数位数。 

sourceColumn

源列的名称。 

sourceVersion

DataRowVersion 值之一。

sourceColumnNullMapping

如果源列可为空,则为 true;如果不可为空,则为 false。

value

一个 Object,它是 SqlParameter 的值。

xmlSchemaCollectionDatabase

此 XML 实例的架构集合所在的数据库的名称。

xmlSchemaCollectionOwningSchema

包含此 XML 实例的架构集合的关系架构。

xmlSchemaCollectionName

此参数的架构集合的名称。

 备注

如果未在 size 和 precision 参数中显式设置 Size 和 Precision,则从 dbType 参数的值推断出它们。

回答2:

在存储过程中添加2个参数

sql语句 例: “update [tablename] username = @username where id=@id”

然后把需要的

command.Parameters.Add(new SqlParameter("@id",SqlDbType.VarChar,50));
cmd.Parameters.Add("@username",textUsername.Text);

标准的system.data.sqlclient
就这个方法

参数必须一个一个添加

也有自己写的 可以传一个new 一个Parameters数组的形式添加进去

"@username" : sql语句中的变量名
SqlDbType.VarChar 变量类型
50 类型的 size。。

作为参数传进入执行,这样能有效的避免一些注入之攻击

补充://
//
command.Parameters.Add(new SqlParameter("@id",SqlDbType.VarChar,50));
//原型
public SqlParameter Add(SqlParameter value);

cmd.Parameters.Add("@username",textUsername.Text);
//原型
public SqlParameter Add(string parameterName, object value);
public SqlParameter Add(string parameterName, SqlDbType sqlDbType);
public SqlParameter Add(string parameterName, SqlDbType sqlDbType, int size);
public SqlParameter Add(string parameterName, SqlDbType sqlDbType, int size, string sourceColumn);

几种 重载 代码里的第一句 是第一种 第二句是第二种

回答3:

虽然是2个不相同的系统里面的.但是这2行代码的作用是一样的.

就是给存储过程传递参数.