如鹏网.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);

 

如鹏网:http://www.rupeng.com

posted @ 2016-03-03 16:50  小居工作室  阅读(390)  评论(0编辑  收藏  举报