第 1 节 类型初始值设定异常和SqlParameter
常见错误:
1.连接字符串中name和代码中不一致错误;
2.SqlParameter对象不可以重复使用(在使用SqlParameter的时候就“随new随用”);
------------------------------------------------
第 2 节 “需要参数但未提供该参数”和bit的值
3.SqlParameter的Value为null和没赋值一样;(不能为null,可以用DBNull.Value)
在数据库中可以为null时,可以使用:
name==null?(object)DBNull.Value:(object)name
SqlParameter.Clear()
4.数据库中,字符类型设置为bit,应该输入数字还是true和false;
sql语句中用0,1
通过sqlParameter传值时用true,false;
在“ManagementStudio”中用true,false
------------------------------------------------
第 3 节 Like和In中查询参数的问题
Console.WriteLine("请输入要查询的姓名");
string name = Console.ReadLine(); //'%@Name%'是一个整体,无法“部分当成查询参数” //DataTable dt = SqlHelper.ExecuteQuery("select * from T_Persons where Name like '%@Name%'", //DataTable dt = SqlHelper.ExecuteQuery("select * from T_Persons where Name like '%'+@Name+'%'", //new SqlParameter("@Name",name)); DataTable dt = SqlHelper.ExecuteQuery("select * from T_Persons where Name like @Name", new SqlParameter("@Name","%"+name+"%")); foreach (DataRow row in dt.Rows) { Console.WriteLine(row["Name"]); } string line = Console.ReadLine(); foreach(char ch in line) { if(!char.IsDigit(ch)&&ch!=',') { Console.WriteLine("输入非法"); Console.ReadKey(); return; } } //DataTable dt = SqlHelper.ExecuteQuery("select * from T_Persons where Age in(@Age)", // new SqlParameter("@Age",line)); // DataTable dt = SqlHelper.ExecuteQuery("select * from T_Persons where Age in(" + line+")"); DataTable dt = SqlHelper.ExecuteQuery("exec('select * from T_Persons where Age in('+@Age+')')", new SqlParameter("@Age",line)); foreach (DataRow row in dt.Rows) { Console.WriteLine(row["Name"]+"="+row["Age"]); }
1.对于加了'@Name'是一个整体,不是参数化查询参数,无法部分是:
1. sqlserver: '%'+@Name+'%'
Mysql: concat('%',@name,'%')
2. new SqlParameter("@Name","%"+name+"%")
2.要sql语句中使用in:
1.拼接(合法性检查): SqlHelper.ExecuteQuery("select * from T_Persons where Age in(" + line+")");
2.使用存储过程:也是存在注入问题,不推荐使用。
SqlHelper.ExecuteQuery("exec('select * from T_Persons where Age in('+@Age+')')", new SqlParameter("@Age",line));
------------------------------------------------
第 4 节 ADO.Net连接SQLServer的事务问题
using (SqlConnection conn = new SqlConnection(connstr))
{
conn.Open();
using (SqlTransaction tx = conn.BeginTransaction()) { try { //using是保证资源一定会被回收的,离开using范围后自动调用Dispose方法(无论是否有异常) //using==try...finally... //using不会进行异常的catch using (SqlCommand cmd1 = conn.CreateCommand()) using (SqlCommand cmd2 = conn.CreateCommand()) { cmd1.Transaction = tx;//在SQLServer中必须把BeginTransaction返回的对象赋值给SqlCommand的 //Transaction属性 cmd1.CommandText = "insert into T_Persons(Name,Age) values('a',1)"; cmd1.ExecuteNonQuery(); cmd2.Transaction = tx; cmd2.CommandText = "insert into T_Persons(Name,Age) values('b',2)"; cmd2.ExecuteNonQuery(); } tx.Commit(); } catch (Exception ex) { tx.Rollback(); } } }
using()是保证资源回收的(try finally),try catch是捕捉异常的。
1.在sqlServer中要先打开连接,再使用事务。
2.在sqlServer中必须把BeginTransaction返回的对象赋值给SqlCommand的对象。(都要写)
建议:
无论是在mysql 还是sqlserver中都要写:
cmd1.Transaction = tx;
cmd2.Transaction = tx;
在sqlhelper中增加事务的重载方法
参数列表:SqlTransaction tx
cmd.Transaction=tx;
------------------------------------------------
第 5 节 SqlBulkCopy
DataTable dt = new DataTable();
dt.Columns.Add("Name"); dt.Columns.Add("Age"); for (int i = 0; i < 80000; i++) { DataRow row = dt.NewRow(); row["Name"] = "aa" + i; row["Age"] = i * i; dt.Rows.Add(row); } using (SqlBulkCopy bulkCopy = new SqlBulkCopy(connstr)) { bulkCopy.DestinationTableName = "T_Persons"; bulkCopy.ColumnMappings.Add("Name", "Name"); bulkCopy.ColumnMappings.Add("Age", "Age"); bulkCopy.WriteToServer(dt); }
使用DataTable 保存80000条数据,然后使用SqlBulkCopy一次性插入到数据库中。
------------------------------------------------
第 6 节 MySQL的批量数据插入:
拼接成1条sql语句。1条SQL语句长度有限(一般每1千条插入一次)
Stopwatch sw = new Stopwatch();
sw.Start();
using (MySqlConnection conn = new MySqlConnection("server=127.0.0.1;database=study1;uid=root;pwd=root")) { conn.Open(); using (MySqlCommand cmd = conn.CreateCommand()) { //一条SQL数据的长度有限 //拼接出1000条数据就批量插入一次 List<string> listSql = new List<string>(); for (int i = 0; i < 100000; i++) { listSql.Add("('test"+i+"','"+i+"')"); if (listSql.Count > 1000) { string sql = "insert into t_users(UserName,Password) values" + string.Join(",", listSql); cmd.CommandText = sql; cmd.ExecuteNonQuery(); listSql.Clear(); } } if (listSql.Count > 0) { //处理残留的数据 string sql1 = "insert into t_users(UserName,Password) values" + string.Join(",", listSql); cmd.CommandText = sql1; cmd.ExecuteNonQuery(); } } } sw.Stop(); Console.WriteLine(sw.ElapsedMilliseconds);
如鹏网:http://www.rupeng.com