您的位置:首页 > 数据库

以编程方式访问数据库

2010-03-31 12:04 239 查看
****************************************************************************
       ****************************************************************************
    对于数据,可以通过声明方式数据绑定,即通过控件,使用Eval和Bind;也可以通过手工编写代码的方式来访问数据库。
数据库的访问,分为以下几步:
 第一步:建立数据库链接;
     创建链接,即创建一个链接实例对象。如下:
  SqlConnection conn=new SqlConnection();
 创建了实例之后,可以通过如下方法给连接配置连接字符串:
  conn.ConnectionString="<connection string>";
 可以将上述两步合为一步,如下:
  SqlConnection conn=new SqlConnection("<connection string>");
 以下为一个完整的connection string:
  connectionString="
      Data Source=./SQLEXPRESS;
      AttachDbFilename=./BegVCDataBase/Test.mdf;
      Integrated Security=True;
      Connect TimeOut=30;
      User Instance=True"
 该链接字符串可以通过“数据库链接”窗口来生成。
 链接字符串通常放置在配置文件中,这样可以多次使用。要访问配置文件信息,可以通过System.Configuration.ConfigurationManager类来实现,该类包含在System.Configuration.dll库中。可以通过这样访问这里的链接字符串:
  SqlConnection conn=new SqlConnection(ConfigurationManager.ConnectionString["MyConnectionString"].ConnectionString);
     链接状态,即数据库的打开或关闭。可以通过SqlConnection.State属性来判断,可以通过SqlConnection.Open()和SqlConnection.Close()来打开和关闭数据库链接。
     可以通过using块来实现数据库的自动关闭,如下:
  using(SqlConnection conn=new SqlConnection(ConfigurationManager.ConnectionStrings["MyConnectionString"].ConnectionString))
  {
   conn.Open();
   ... ...
  }
     也可以通过try...catch...finally结构来关闭数据库链接,如下:
  try
  {
   conn.Open();
   ... ...
  }
  catch(Exception ex)
  {
   //异常处理
  }
  finally
  {
   conn.Close();
  }
        ********
 *连接池*
 ********
 优化数据库连接,高级主题。应用于多线程的应用程序。

 第二步:执行SQL语句;
  1.创建命令
  SqlCommand对象有4个构造函数,如下:
     默认无参构造函数:
  SqlCommand cmd=new SqlCommand();
     最复杂的有3个参数:
  SqlCommand cmd=new SqlCommand("<command string>、<connection>、<transaction>");
  <command string>:定义命令字符串,SQL语句。该命令取决于命令的类型,可以通过SqlCommand.CommandText属性来设置该字符串;
  <connection>:对SqlConnection对象的引用。可以通过SqlCommand.Connection属性来设置;
 ////////<transaction>:将命令包含在事务中;////////

  2.命令类型
         Sql Server客户端支持三中命令类型,由SqlCommand.CommandType属性设定。
     CommandType.Text:默认值,指定其为SQL命令。
     CommandType.TableDirect:指定其为表或试图名称,执行后返回指定表中的所有行和列。
     CommandType.StoredProcedure:指定包含存储过程的名称。
  举例如下:
  SqlCommand cmd=new SqlCommand("MyTable",conn);
  cmd.CommandType=CommandType.TableDirect;
  3.执行命令的方法
     命令的类型和执行命令的方法,决定了返回的结果。用于执行命令的方法如下:
  ExecuteNonQuery():返回一个int类型值,表示影响的哪行,该方法适用于Insert、Update、Delete命令。
  ExecuteReader():返回一个SqlDataReader对象,用于操作行数据,适用于Select命令。
  ExecuteScalar():返回类型为Object,这一方法用于要求返回任意类型的结果。不适用于Select命令。
  ExecuteXmlReader():返回XmlReader对象,执行此命令返回XML数据。
  ////////这几个方法有异步版本,异步方法获得阅读器对象时,使用BeginExecuteReader()方法等等,更///////////////////////多信息参考其他资源。
     对于上述提到的ExecuteReader方法,可以使用CommandBehavior枚举指定其命令行为:
  具体枚举成员略,参见MSDN。其作用是:提供对查询结果和查询对数据库的影响的说明。
  4.参数化命令
     使用参数化命令,有助于防止SQL注入攻击,同时有助于复用命令。 
     使用参数化命令,必须在SqlCommand.Parameters集合中通过Add()方法添加参数,可以指定参数的名称、参数类型、列长度和参数的源列等信息。配置参数后,通过Value属性指定其值,可以将添加和设置以步完成,如下:
  SqlCommand cmd=new("SQL * FROM MyTable WHERE MyId=@MyId",conn);
  cmd.Paramers.Add("@MyId",SqlDype.UniqueIdentifier).Value=MyGuidVar;
     需要注意的是,这种方法设定的是出入参数,可以使用如下方法设定输入参数和双向参数:
  SqlParameter param=new SqlParamer("@MyId",SqlType.Int);
  param.Direction=ParamDirection.Output. 
  实例:
  SqlParameter param=new SqlParameter();
  param.patameterName="@MyId";
  param.DbType=DbType.Int32;
  param.Direction=ParameterDirection.Input;
  cmd.Patamters.Add(param);
     使用参数化命令,可以减少注入攻击的危险。可以在SqlCommand.Parameters集合中添加相应的参数,该集合是SqlParametersCollection类的一个实例,包含SqlParameter对象,使用SqlParametersCollection.Add()方法添加参数。如下:
  5.防范SQL注入攻击。
  通过过滤单引号(')的方法类防止,使用替换:
  userInput=userInput.Replace("'","''");
  最主要的方法还是使用参数化查询来生成SQL语句。
  SqlCommand cmd =new SqlCommand("SELECT * FROM MyTable WHERE MyID=@MyID",conn);
  cmd.Parameters.Add("@MyID",SqlDbType.UniqueIdentifier).Value=MyGuidVar
     完整举例如下:
  string query ="SELECT * FROM " + tableName ;//注意FROM应有一个空格
  SqlCommand cmd=new SqlCommand(query,conn);
**************************************************************************
 第三步:管理数据库对象,操作数据。
**************************************************************************
     1.数据阅读器对象SqlDataReader
**************************************************************************
  用于读取执行指令获得的数据,只能向前阅读,每次一行。
     创建数据阅读器对象DataReaderr,该对象只能使用SqlCommand.ExecuteReader()方法执行命令来获得,即没有SqlDataReader类的实例公有构造函数。
     应用举例:
  SqlCommand cmd=new SqlCommand("SELECT * FROM MyTable",conn);
   SqlDataReader reader=cmd.ExecuteReader();
     2.读取数据
  数据阅读器可以读取数据的以下信息:
      架构数据:
      行数据:
      其他属性,如行信息,多少行等。
     ****获取数据架构信息:
  SqlDataReader.GetSchemaTable()方法返回DataTable实例,包含列的索引、名称、类型、长度、键信息等列信息。也可以单独获取某一方面的信息:
  SqlDataReader.FieldCount:获取数据阅读器的列数,返回值为int值;
  SqlDataReader.GetName():获取制定列的名称(列用int索引制定);
  SqlDataReader.GetDataTypeName():获取指定列的数据类型名(列用int索引制定),返回string类型值。
     ****行数据:
  在阅读数据前应先加载数据,使用Read()方法来加载行。首次加载,返回一个布尔值,让调用者知道是否加载成功,加载完成后返回false。故通常使用while循环来读取数据。
  提取列信息对行数据进行处理时,可以使用两种方法将列数据提取为特定的数据类型:
      第一种:使用SqlDataReader的GetValue()方法和GetSqlValues()方法,举例如下:
   SqlDataReader reader=cmd.ExecuteReader();
   object columnVal1=reader.GetValue(0);
      第二种:使用SelDataReader索引器,举例如下:
   SqlDataReader reader=cmd.ExecuteReader();
   object columnVal2=reader(0);
  使用第二种方法,需要的代码少,需要将值强制类型转换,SQL数据类型在命名空间System.Data.SqlType中,同时使用索引器使得可以用其重载版本,可以通过列名来访问列,如:
   object columnVal3=reader["MyColumn"];
  但是,使用第二种方法的缺点是,比较慢。
  需要注意的是,在使用强制类型转换的时候,应该合理处理空值。使用上述两种方法遇到空值时,返回的结果是System.DBNull,在处理数据时要小心由于空值引起的异常。
  最后,需要获取大量二进制或文本数据时,可以使用SqlDataReader对象的GetBytes()、GetSqlBytes()、GetChars()和GetSqlChars()等方法,但是数据访问器行为必须声明为CommandBehavior.Sequential时才能使用上述方法。
     ****其他属性
  FieldCount:获取行中的列数。
  HasRaws:判断数据阅读器中是否还有行。
  IsClosed:判断数据阅读器是否关闭。
  RecordAffected:指出数据阅读器影响的行数,这个属性在数据阅读器关闭之后才能正确使用。
  VisibleFieldCount:获得隐藏的列数。
  Depth:当前加载行的嵌套程度。
  3.数据阅读器对象的连接
     数据阅读器在使用中,其底层的SqlConnection对象不能使用其他用途,如果需要,可以通过SqlDataReader.Connection属性访问其底层连接,但唯一能执行的操作时调用连接的Close()方法关闭它。使用数据阅读器来获取表数据:
  {
    //配置链接数据库
   SqlConnection conn=new SqlConnection(ConfigurationManager.ConnectionString["FolktableConnectionString"].ConnectionString);
   //获取用户输入数据列表名
   Console.WriteLine("Enter table from which to output data:");
   //获取输入表名
   string tablename=Console.ReadLine();
   //判断是否有SQL注入攻击
   if(tablename.IndexOf(';')!=-1)
   {
    Console.WriteLine("Sql injection attack detected.Press ENTER to close.");
    Console.Read();
    return;
   }
   //防止SQL注入攻击
   tablename=tablename.Replace("'","''");
   //创建命令
   string query="SELECT * FROM "+tablename;//注意FROM后应有一个空格
   SqlCommand cmd=new SqlCommand(query,conn);

   try
   {
    conn.Open();
    SqlDataReader reader=cmd.ExecuteReader();
    while(reader.Read())
    {
     for(int index=0;index<reader.FieldCount;index++)
     {
      Console.WriteLine(reader.GetName(index)+":"+reader[index].ToString()+";"); 
     }
     Console.WriteLine();
    }
    reader.Close();   //注意这里,即调用Close()方法关闭数据阅读器连接
   }
   catch(Exception ex)
   {
    //异常处理
   }
   finally
   {
    conn.Close();//关闭数据库连接
   }
   Console.WriteLine("Press ENTER to close.");
   Console.ReadLine();
        }
    }
  }

 

 

 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息