如鹏网.Net基础2 ADO.Net专题课
第 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);