C#中SqlParameter的作用与用法

般来说,在更新DataTable或是DataSet时,如果不采用SqlParameter,那么当输入的Sql语句出现歧义时,如字符串中含有单引号,程序就会发生错误,并且他人可以轻易地通过拼接Sql语句来进行注入攻击。

​​


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18



​string​​ ​​sql
= ​
​​​"update
Table1 set name = 'Pudding' where ID = '1'"​
​​​;​​​​//未采用SqlParameter​

​SqlConnection
conn = ​
​​​new​​ ​​SqlConnection();​

​conn.ConnectionString
= ​
​​​"Data
Source=.\\SQLExpress;Integrated Security=true;AttachDbFilename=|DataDirectory|\\Database.mdf;User Instance=true"​
​​​;​​​​//连接字符串与数据库有关​

​SqlCommand
cmd = ​
​​​new​​ ​​SqlCommand(sql,
conn);​

​try​

​{​

​conn.Open();​

​return​​​​(cmd.ExecuteNonQuery());​

​}​

​catch​​ ​​(Exception)​

​{​

​return​​ ​​-1;​

​throw​​​​;​

​}​

​finally​

​{​

​conn.Close();​

​}​


上述代码未采用SqlParameter,除了存在安全性问题,该方法还无法解决二进制流的更新,如图片文件。通过使用SqlParameter可以解决上述问题,常见的使用方法有两种,Add方法和AddRange方法。

一、Add方法

​?​


1

2

3

4



​SqlParameter
sp = ​
​​​new​​ ​​SqlParameter(​​​​"@name"​​​​,​​​​"Pudding"​​​​);​

​cmd.Parameters.Add(sp);​

​sp
= ​
​​​new​​ ​​SqlParameter(​​​​"@ID"​​​​,​​​​"1"​​​​);​

​cmd.Parameters.Add(sp);​


  该方法每次只能添加一个SqlParameter。上述代码的功能是将ID值等于1的字段name更新为Pudding(人名)。

二、AddRange方法

​?​


1

2



​SqlParameter[]
paras = ​
​​​new​​ ​​SqlParameter[]
{ ​
​​​new​​ ​​SqlParameter(​​​​"@name"​​​​,​​​​"Pudding"​​​​),​​​​new​​ ​​SqlParameter(​​​​"@ID"​​​​,​​​​"1"​​​​)
};​

​cmd.Parameters.AddRange(paras);​


  显然,Add方法在添加多个SqlParameter时不方便,此时,可以采用AddRange方法。

  下面是通过SqlParameter向数据库存储及读取图片的代码。

​?​


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58



​public​​ ​​int​​ ​​SavePhoto(​​​​string​​ ​​photourl)​

​{​

​FileStream
fs = ​
​​​new​​ ​​FileStream(photourl,
FileMode.Open, FileAccess.Read);​
​​​//创建FileStream对象,用于向BinaryReader写入字节数据流​

​BinaryReader
br = ​
​​​new​​ ​​BinaryReader(fs);​​​​//创建BinaryReader对象,用于写入下面的byte数组​

​byte​​​​[]
photo = br.ReadBytes((​
​​​int​​​​)fs.Length);​​​​//新建byte数组,写入br中的数据​

​br.Close();​​​​//记得要关闭br​

​fs.Close();​​​​//还有fs​

​string​​ ​​sql
= ​
​​​"update
Table1 set photo = @photo where ID = '0'"​
​​​;​

​SqlConnection
conn = ​
​​​new​​ ​​SqlConnection();​

​conn.ConnectionString
= ​
​​​"Data
Source=.\\SQLExpress;Integrated Security=true;AttachDbFilename=|DataDirectory|\\Database.mdf;User Instance=true"​
​​​;​

​SqlCommand
cmd = ​
​​​new​​ ​​SqlCommand(sql,
conn);​

​SqlParameter
sp = ​
​​​new​​ ​​SqlParameter(​​​​"@photo"​​​​,
photo);​

​cmd.Parameters.Add(sp);​

​try​

​{​

​conn.Open();​

​return​​ ​​(cmd.ExecuteNonQuery());​

​}​

​catch​​ ​​(Exception)​

​{​

​return​​ ​​-1;​

​throw​​​​;​

​}​

​finally​

​{​

​conn.Close();​

​}​

​}​

 

​public​​ ​​void​​ ​​ReadPhoto(​​​​string​​ ​​url)​

​{​

​string​​ ​​sql
= ​
​​​"select
photo from Table1 where ID = '0'"​
​​​;​

​SqlConnection
conn = ​
​​​new​​ ​​SqlConnection();​

​conn.ConnectionString
= ​
​​​"Data
Source=.\\SQLExpress;Integrated Security=true;AttachDbFilename=|DataDirectory|\\Database.mdf;User Instance=true"​
​​​;​

​SqlCommand
cmd = ​
​​​new​​ ​​SqlCommand(sql,
conn);​

​try​

​{​

​conn.Open();​

​SqlDataReader
reader = cmd.ExecuteReader();​
​​​//采用SqlDataReader的方法来读取数据​

​if​​ ​​(reader.Read())​

​{​

​byte​​​​[]
photo = reader[0] ​
​​​as​​ ​​byte​​​​[];​​​​//将第0列的数据写入byte数组​

​FileStream
fs = ​
​​​new​​ ​​FileStream(url,FileMode.CreateNew);创建FileStream对象,用于写入字节数据流​

​fs.Write(photo,0,photo.Length);​​​​//将byte数组中的数据写入fs​

​fs.Close();​​​​//关闭fs​

​}​

​reader.Close();​​​​//关闭reader​

​}​

​catch​​ ​​(Exception
ex)​

​{​

​throw​​​​;​

​}​

​finally​

​{​

​conn.Close();​

​}​​​​}​​}