当前位置: 首页 > news >正文

如何开网站呢外包网络安全技术措施

如何开网站呢,外包网络安全技术措施,校园网站建设培训稿,wordpress 怎么置顶VC使用ADO开发ACCESS数据库 ADO和ADOX到底是什么#xff0c;二者的作用和区别 ADO是Microsoft 最新推出的数据库访问的高层软件接口。它和Microsoft以前的数据库访问接口DAO、RDO相比具有更大的灵活性#xff0c;使用也更方便#xff0c;开发效率大为提高。 ADOX是核心AD…VC使用ADO开发ACCESS数据库 ADO和ADOX到底是什么二者的作用和区别 ADO是Microsoft 最新推出的数据库访问的高层软件接口。它和Microsoft以前的数据库访问接口DAO、RDO相比具有更大的灵活性使用也更方便开发效率大为提高。 ADOX是核心ADO对象的扩展库。它提供的附加对象可用于创建、修改和删除模式对象如表和过程。要使用ADOX则应建立对ADOX类型库的引用。ADOX库文件名为Msadox.dll。 通俗地讲ADO是访问数据库的一种接口可以使用它方便地进行数据库编程。而ADOX是微软对ADO功能的扩展比如可以ADOX创建数据库而ADO没有创建数据库的功能。 ADOX创建ACCESS数据库 用ADOX创建access数据库方法很简单只需要创建一个Catalog对象然后调用它的Create方法就可以了。 例程ADOXCreateDatabase演示如何使用ADOX创建一个ACCESS数据库。 打开VC 6.0新建一个基于对话框的工程ADOXCreateDatabase。在对话框IDD_ADOXCREATEDATABASE_DIALOG中添加一个编辑框IDC_DBNAME和一个按钮IDC_BTN_CREATE编辑框用以输入数据库名称。 使用ClassWizard给编辑框创建一个CString变量m_dbName。 双击IDC_BTN_CREATE按钮并编辑OnBtnCreate()函数如下 void CADOXCreateDatabaseDlg::OnBtnCreate() { //使输入到编辑框IDC_DBNAME的内容更新到m_dbName变量中 UpdateData(TRUE); CString str; strd:\\m_dbName.mdb; //检查该数据库是否已经存在如果该数据库已经存在弹出消息框返回 //使用API函数PathFileExists()检查路径文件是否存在 //请注意为了使用API函数PathFileExists()需要加入 //#include Shlwapi.h //#pragma comment(lib,shlwapi.lib) if(PathFileExists(str)) { CString strTemp; strTemp.Format(%s已存在!,str); AfxMessageBox(strTemp); return ; } //定义ADOX对象指针并初始化为NULL //用ADOX创建access数据库方法很简单 //只需要新建一个Catalog对象然后调用它的Create方法就可以了。 //Catalog是 ADOX 的一个对象它包含描述数据源模式目录的集合。 //在这里您只需知道创建数据库时使用这个对象就可以了。 //注意用try...catch组合捕捉错误 _CatalogPtr m_pCatalog NULL; CString DBNameProviderMicrosoft.JET.OLEDB.4.0;Data source; DBNameDBNamestr; try { m_pCatalog.CreateInstance(__uuidof(Catalog)); m_pCatalog-Create(_bstr_t((LPCTSTR)DBName)); } catch(_com_error e) { AfxMessageBox(e.ErrorMessage()); return ; }     } 使用ADOX需要引入ADOX的动态链接库msadox.dll即在stdafx.h中加入如下语句 #import C:\Program Files\Common Files\system\ado\msadox.dll no_namespace rename(EOF,adoEOF) 另外ADOX属于COM对象所以要在CADOXCreateDatabaseApp::InitInstance()函数中加入 if(!AfxOleInit()) { AfxMessageBox(OLE初始化出错); return FALSE; } 初始化COM。 编译并运行该例程对于编译过程中弹出的4146号警告不要理会。在编辑框中输入一个数据库名称点击“创建数据库”按钮该数据库将在d盘根目录下创建再次输入该数据库名称并点击“创建数据库”按钮将弹出警告对话框。 在VC中使用ADO的时候会得到4146号警告信息我们可以不去理会也可以通过#pragma warning指令解决方法为在stdafx.h中加入的语句 #import C:\Program Files\Common Files\system\ado\msadox.dll no_namespace rename(EOF,adoEOF) 前后再加一条语句修改后为 #pragma warning (disable:4146) #import C:\Program Files\Common Files\system\ado\msadox.dll no_namespace rename(EOF,adoEOF) #pragma warning (default:4146) 指令#pragma warning (disable:4146) 暂时屏蔽编译时4146警告信息 指令#pragma warning (default:4146) 重置编译器的4146警告到默认状态 ADO创建ACCESS数据库的表 我们一般用ADOX创建数据库然后再用ADO创建数据库的表。 例程CREATE_DB_AND_TABLE演示如何使用ADO创建ACCESS数据库的表。 打开VC 6.0新建一个基于对话框的工程CREATE_DB_AND_TABLE。在对话框IDD_CREATE_DB_AND_TABLE_DIALOG中添加如下控件 控件名称 ID 用途 编辑框 IDC_DBNAME 输入数据库名称 按钮 IDC_BTN_CREATE 创建数据库 编辑框 IDC_TABLENAME 输入表名 按钮 IDC_BTN_CREATE_TABLE 创建表 使用ClassWizard给两个编辑框创建CString变量 编辑框 CString变量 编辑框IDC_DBNAME m_dbName 编辑框IDC_TABLENAME m_tableName 双击IDC_BTN_CREATE按钮并编辑OnBtnCreate()函数如下 void CADOXCreateDatabaseDlg::OnBtnCreate() { UpdateData(TRUE); CString str; strd:\\m_dbName.mdb; if(PathFileExists(str)) { CString strTemp; strTemp.Format(%s已存在!,str); AfxMessageBox(strTemp); return ; } _CatalogPtr m_pCatalog NULL; CString DBNameProviderMicrosoft.JET.OLEDB.4.0;Data source; DBNameDBNamestr; try { m_pCatalog.CreateInstance(__uuidof(Catalog)); m_pCatalog-Create(_bstr_t((LPCTSTR)DBName)); } catch(_com_error e) { AfxMessageBox(e.ErrorMessage()); return ; }     } 以上代码例程ADOXCreateDatabase中已经详细叙述。 双击IDC_BTN_CREATE_TABLE按钮并编辑OnBtnCreateTable()函数如下 void CCREATE_DB_AND_TABLEDlg::OnBtnCreateTable() { //先判断表名编辑框是否为空 UpdateData(TRUE); if(!m_tableName.IsEmpty()) { ADOX::_CatalogPtr m_pCatalogNULL; ADOX::_TablePtr m_pTableNULL; CString str; strd:\\m_dbName.mdb; CString DBNameProviderMicrosoft.JET.OLEDB.4.0;Data source; DBNameDBNamestr; //这段代码先检查表是否已经存在如果表已经存在不再创建直接返回。 //其实这段代码不必深入研究只需知道它的功能直接拿来使用即可 try { m_pCatalog.CreateInstance(__uuidof(ADOX::Catalog)); m_pCatalog-PutActiveConnection(_bstr_t(DBName)); int tableCountm_pCatalog-Tables-Count; int i0; while(itableCount) { m_pTable(ADOX::_TablePtr)m_pCatalog-Tables-GetItem((long)i); CString tableName(BSTR)m_pTable-Name; if(tableNamem_tableName) { AfxMessageBox(该表已经存在!); return; } i; } } catch(_com_error e) { AfxMessageBox(e.Description()); return; } ADODB::_ConnectionPtr m_pConnection; //创建表 _variant_t RecordsAffected; try { m_pConnection.CreateInstance(__uuidof(ADODB::Connection)); //Open方法的原型 //Open(_bstr_t ConnectionString,_bstr_t UserID,_bstr_t Password,long Options) //ConnectionString为连接字串UserID是用户名Password是登陆密码 //Options是连接选项可以是如下几个常量 //adModeUnknown 缺省当前的许可权未设置 //adModeRead 只读 //adModeWrite 只写 //adModeReadWrite 可以读写 //adModeShareDenyRead 阻止其它Connection对象以读权限打开连接 //adModeShareDenyWrite 阻止其它Connection对象以写权限打开连接 //adModeShareExclusive 阻止其它Connection对象打开连接 //adModeShareDenyNone 阻止其它程序或对象以任何权限建立连接 m_pConnection-Open(_bstr_t(DBName),,,ADODB::adModeUnknown); } catch(_com_error e) { CString errormessage; errormessage.Format(连接数据库失败!\r错误信息:%s,e.ErrorMessage()); AfxMessageBox(errormessage); return; } try { CString strCommand; /* 执行SQL命令CREATE TABLE创建表格 该表包含三个字段记录编号 INTEGER,姓名 TEXT,出生年月 DATETIME    SQL语言中的create table语句被用来建立新的数据库表格。 create table语句的使用格式如下 create tablename (column1 data type,column2 data type,column3 data type); 如果用户希望在建立新表格时规定列的限制条件可以使用可选的条件选项 create table tablename (column1 data type[constraint], column2 data type[constraint], column3 data type[constraint]); 举例 create table employee (firstname varchar(15), lastname varchar(20), age number(3), address varchar(30), city varchar(20)); 简单来说创建新表格时在关键词create table后面加入所要建立的表格的名称然后在括号内顺次设定各列的名称数据类型以及可选的限定条件等。 使用SQL语句创建的数据库表格和表格中列的名称必须以字母开头后面可以使用字母数字或下划线名称的长度不能超过30个字符注意用户在选择表格名称时不要使用SQL语言中的保留关键字如select,create,insert等作为表格或列的名称。 */ strCommand.Format(CREATE TABLE %s(记录编号 INTEGER,姓名 TEXT,出生年月 DATETIME),m_tableName); //Execute(_bstr_t CommandText,VARIANT* RecordsAffected,long Options) //其中CommandText是命令字串通常是SQL命令 //参数RecordsAffected是操作完成后所影响的行数 //参数Options表示CommandText中内容的类型可以取下列值之一 //adCmdText 表明CommandText是文本命令 //adCmdTable 表明CommandText是一个表名 //adCmdProc 表明CommandText是一个存储过程 //adCmdUnknown 未知 m_pConnection-Execute(_bstr_t(strCommand),RecordsAffected,ADODB::adCmdText); if(m_pConnection-State) m_pConnection-Close(); } catch(_com_error e) { AfxMessageBox(e.Description()); } } } 这段代码先用ADOX的Catalog对象检查表是否已经存在如果该表已经存在直接返回如果还没有该表使用ADO的Connection对象的Execute函数创建表。 Connection对象的用法首先定义一个Connection类型的指针然后调用CreateInstance()来创建一个连接对象的实例再调用Open函数建立与数据源的连接。最后使用Execute()函数执行SQL语句创建表。 关于调用CreateInstance()来创建连接对象的实例还需作一点说明。ADO库包含三个基本接口_ConnectionPtr接口_RecordsetPtr接口和_CommandPtr接口。其分别对应Connection对象完成应用程序对数据源的访问连接Recordset对象将查询的结果以记录集的方式存储和Command对象对已连接的数据源进行命令操作。 _ConnectionPtr m_pConnection; _RecordsetPtr m_pRecordset; _CommandPtr m_pCommand; 而这三个对象实例的创建可以使用如下语句 m_pConnection.CreateInstance(__uuidof(Connection)); 或者 m_pConnection.CreateInstance(“ADODB.Connection”); m_pRecordset.CreateInstance(__uuidof(Recordset)); 或者 m_pRecordset.CreateInstance(“ADODB.Recordset”); m_pCommand.CreateInstance(__uuidof(Command)); 或者 m_pCommand.CreateInstance(“ADODB.Command”); 两种方法的作用完全相同使用哪种方法完全是您的个人爱好问题。 如例程ADOXCreateDatabase在BOOL CCREATE_DB_AND_TABLEApp::InitInstance()函数中加入 if(!AfxOleInit()) { AfxMessageBox(OLE初始化出错); return FALSE; } 在stdafx.h中加入如下语句 #import C:\Program Files\Common Files\system\ado\msadox.dll #import C:\Program Files\Common Files\system\ado\msado15.dll rename(EOF,adoEOF) 关于这两条语句需要进行特别说明 由于该例程同时使用ADOX和ADO需要同时引入msado15.dll和msadox.dll两个库。这两个库的名字空间是不同的msado15.dll的名字空间是ADODBmsadox.dll的名字空间是ADOX。在使用ADO所属的名字空间的变量函数时在前面加上ADODB::在使用ADOX所属的名字空间的变量函数时在前面加上ADOX::。 另外一般ADOX和ADO分开操作。您也可以在ADOX操作部分使用using namespace ADOX::而在ADO操作部分使用using namespace ADO:以区分名字空间。这样您就不必再使用ADOX::和ADODB::了。 rename(“EOF”,”adoEOF”) //重命名EOF是必要的因为典型的VC应用都已经定义了EOF作为常数1为了避免冲突将ADO中的EOF重命名为adoEOF。 #import中有一个属性为no_namespace这是告诉编译器该类不在一个单独的名字空间中使用no_namespace意味着你不需要在初始化变量的时候引用名字空间。当然如果在您的应用中需要导入多个类型库的话不要使用no_namespace以免引起名字冲突。 再通俗一点讲就是只导入一个类型库的话可以在#import语句中加入no_namespace属性您的程序可以直接使用这个类型库的名字空间的内容而不必使用using namespace XXX;或XXX::这是因为no_namespace属性告诉编译器该类型库不再名字空间而是在全局空间上工作如果您导入几个类型库而这几个类型库之间没有定义冲突您也可以在使用no_namespace属性但如果两个类型库中有定义冲突就不能使用no_namespace属性如果使用no_namespace属性就会在全局空间产生定义冲突。 对于本例程您可以把stdafx.h中的 #import C:\Program Files\Common Files\system\ado\msadox.dll #import C:\Program Files\Common Files\system\ado\msado15.dll rename(EOF,adoEOF) 改为 #import C:\Program Files\Common Files\system\ado\msadox.dll #import C:\Program Files\Common Files\system\ado\msado15.dll no_namespace  rename(EOF,adoEOF) 这样改动后void CCREATE_DB_AND_TABLEDlg::OnBtnCreateTable()中的ADODB::需要完全省略掉。 当然您也可以把这两行改为 #import C:\Program Files\Common Files\system\ado\msadox.dll no_namespace #import C:\Program Files\Common Files\system\ado\msado15.dll rename(EOF,adoEOF) 但这样改动后void CCREATE_DB_AND_TABLEDlg::OnBtnCreateTable()中的ADOX::需要完全省略掉。 由于ADOX和ADO有定义冲突也就是说msado15.dll和msadox.dll有相同的定义部分所以在一个程序中不允许同时使用no_namespace。 使用_ConnectionPtr接口开发ACCESS数据库 ADO中最重要的对象有三个Connection、Recordset和Command分别表示连接对象、记录集对象和命令对象。三个对象对应的智能指针分别是_ConnectionPtr、_RecordsetPtr、_CommandPtr。ADO使用_ConnectionPtr这个指针来操纵Connection对象类似地后面用到的_CommandPtr和_RecordsetPtr分别表示命令对象指针和记录集对象指针。 Connection对象是这三个对象的基础它的主要作用是建立与数据库的连接建立了与数据库的连接后才能进行其它有关数据库的访问和操作。 也就是说使用ADO操作数据库通常先用Connection对象的Open方法打开一个库连接然后才能进行数据库的操作。操作完成后要关闭这个库连接。 本文只讲述Connection对象最常用的Open方法和Execute方法。Open方法用于打开一个库连接而Execute方法一般用于执行一条SQL语句。 _ConnectionPtr智能指针的用法 首先定义一个Connection类型的指针然后调用CreateInstance()来创建一个连接对象的实例再调用Open函数建立与数据源的连接。在建立连接对象后可以使用连接对象的Execute()函数来执行SQL命令。 _ConnectionPtr智能指针Open方法的原型 Open(_bstr_t ConnectionString,_bstr_t UserID,_bstr_t Password,long Options) ConnectionString为连接字串UserID是用户名Password是登陆密码 Options是连接选项可以是如下几个常量 adModeUnknown 缺省当前的许可权未设置 adModeRead 只读 adModeWrite 只写 adModeReadWrite 可以读写 adModeShareDenyRead 阻止其它Connection对象以读权限打开连接 adModeShareDenyWrite 阻止其它Connection对象以写权限打开连接 adModeShareExclusive 阻止其它Connection对象打开连接 adModeShareDenyNone 阻止其它程序或对象以任何权限建立连接 _ConnectionPtr智能指针Execute方法的原型 _RecordsetPtr Connection15::Execute(_bstr_t CommandText,VARIANT* RecordsAffected,long Options) 其中CommandText是命令字串通常是SQL命令 参数RecordsAffected是操作完成后所影响的行数 参数Options表示CommandText中内容的类型可以取下列值之一 adCmdText 表明CommandText是文本命令 adCmdTable 表明CommandText是一个表名 adCmdProc 表明CommandText是一个存储过程 adCmdUnknown 未知 Execute执行完后返回一个指向记录集的指针。 例程CREATE_DB_AND_TABLE中已经使用了_ConnectionPtr指针的Open方法和Execute方法在后面的例程我们将进一步详细说明。 我们先讲解几条最常用的SQL语句。 SELECT查询语句 我们希望用各种不同的方法来查看和分析数据SELECT语句就是我们要使用的语句用于有选择的从数据库返回我们需要的数据也就是查询。 最基本的SELECT语句仅有两个部分要返回的列和这些列源于的表 为了便于讲解演示我们使用如下Northwind 示例数据库中的 Employees 表 EmployeeID FirstName LastName HireDate City Country 1 Nancy Davolio 1/5/1992 12:00:00 Seattle USA 2 Andrew Fuller 14/8/1992 12:00:00 Tacoma USA 3 Janet Leverling 1/4/1992 12:00:00 Kirkland USA 4 Margaret Peacock 3/5/1993 12:00:00 Redmond USA 5 Steven Buchanan 17/10/1993 12:00:00 London UK 6 Michael Suyama 17/10/1993 12:00:00 London UK 7 Robert King 2/1/1994 12:00:00 London UK 8 Laura Callahan 5/3/1994 12:00:00 Seattle USA 9 Anne Dodsworth 15/11/1994 12:00:00 London UK 如果我们希望检索Employees表中所有客户的所有信息我们可以使用星号*来简单地表示所有列查询语句如下所示 SELECT * FROM Employees 如果我们只需要特定列我们应该在逗号分隔的列表中显式指定这些列如下所示 SELECT EmployeeID, FirstNameLastNameHireDate FROM Employees 结果会显示该表中所有行的指定字段的数据。 显式指定所需字段还允许我们控制字段返回的顺序如果我们希望LastName显示在FirstName之前我们可以编写以下语句 SELECT EmployeeID, LastNameFirstNameHireDate FROM Employees WHERE子句 接下来我们要做的是开始限制或筛选从数据库提取的数据。通过向SELECT语句添加WHERE子句我们可以添加一个或多个条件所选数据必须满足这些条件这将限制答复查询的行数也就是被提取的行数。 我们可以在上一个查询的基础上将其限制为City为London的员工 SELECT EmployeeID, FirstName, LastName, HireDate, City FROM Employees WHERE City London 查询结果如下 EmployeeID FirstName LastName HireDate City 5 Steven Buchanan 17/10/1993 12:00:00 London 6 Michael Suyama 17/10/1993 12:00:00 London 7 Robert King 2/1/1994 12:00:00 London 9 Anne Dodsworth 15/11/1994 12:00:00 London 如果您希望返回相反条件的员工即返回那些不住在伦敦的员工您应该编写以下语句 SELECT EmployeeID, FirstName, LastName, HireDate, City FROM Employees WHERE City London 您也可以使用大于、小于、大于等于、小于等于等运算符。例如若要获取其雇佣日期等于某个给定日期或大于该日期的员工列表您可以编写以下语句 SELECT EmployeeID, FirstName, LastName, HireDate, City FROM Employees WHERE HireDate 1-july-1993 您可以得到以下结果行 EmployeeID FirstName LastName HireDate City 5 Steven Buchanan 17/10/1993 12:00:00 London 6 Michael Suyama 17/10/1993 12:00:00 London 7 Robert King 2/1/1994 12:00:00 London 8 Laura Callahan 5/3/1994 12:00:00 Seattle 9 Anne Dodsworth 15/11/1994 12:00:00 London 当然我们可以编写更复杂的条件在 WHERE 子句中加入多个条件。如果我们希望了解哪些员工是在两个给定日期之间雇佣的我们可以编写以下语句 SELECT     EmployeeID, FirstName, LastName, HireDate, City FROM       Employees WHERE      (HireDate 1-june-1992) AND (HireDate 15-december-1993) 结果如下 EmployeeID FirstName LastName HireDate City 2 Andrew Fuller 14/8/1992 12:00:00 Tacoma 4 Margaret Peacock 3/5/1993 12:00:00 Redmond 5 Steven Buchanan 17/10/1993 12:00:00 London 6 Michael Suyama 17/10/1993 12:00:00 London SQL还有一个BETWEEN 运算符用于检查某个值是否在两个值之间包括等于两端的值。这使我们可以将以前的查询重新编写为 SELECT    EmployeeID, FirstName, LastName, HireDate, City FROM      Employees WHERE     HireDate BETWEEN 1-june-1992 AND 15-december-1993 我们也可以使用 NOT 运算符来提取那些不在指定日期之间的行 SELECT    EmployeeID, FirstName, LastName, HireDate, City FROM      Employees WHERE     HireDate NOT BETWEEN 1-june-1992 AND 15-december-1993 如果我们希望检查一个列值是否等于多个值那该怎么办呢如果只是两个值则很容易对每个值进行测试方法是使用 OR 运算符将它们连接在一起则编写的语句如下所示 SELECT EmployeeID, FirstName, LastName, HireDate, City FROM Employees WHERE City London OR City Seattle 但是如果您希望与三个、四个或更多值进行比较则上述方法就行不通了。在这种情况下我们可以使用 IN 运算符来对一组值进行测试。如果我们希望查看 City 是否为 Seattle、Tacoma 或 Redmond我们可以编写以下语句 SELECT EmployeeID, FirstName, LastName, HireDate, City FROM Employees WHERE City IN (Seattle, Tacoma, Redmond) 显示以下结果 EmployeeID FirstName LastName HireDate City 1 Nancy Davolio 1/5/1992 12:00:00 Seattle 2 Andrew Fuller 14/8/1992 12:00:00 Tacoma 4 Margaret Peacock 3/5/1993 12:00:00 Redmond 8 Laura Callahan 5/3/1994 12:00:00 Seattle 我们也可以获得所含结果的相反条件下的结果即查询那些 City 不在指定列表中的行 SELECT EmployeeID, FirstName, LastName, HireDate, City FROM Employees WHERE City NOT IN (Seattle, Tacoma, Redmond) 最后要说明的是LIKE 运算使我们可以使用通配符来执行基本的模式匹配。在 Microsoft SQL Server 中定义的通配符包含以下字符 通配符 说明 _下划线 与任意单字符匹配 % 与包含一个或多个字符的字符串匹配 [ ] 与特定范围例如[a-f]或特定集例如[abcdef]中的任意单字符匹配。 [^] 与特定范围例如[^a-f]或特定集例如[^abcdef]之外的任意单字符匹配。 以下一些示例可以帮助阐明上述规则。 WHERE FirstName LIKE _im 可以找到所有三个字母的、以 im 结尾的名字例如Jim、Tim。 WHERE LastName LIKE %stein 可以找到姓以 stein 结尾的所有员工。 WHERE LastName LIKE %stein% 可以找到姓中任意位置包括 stein 的所有员工。 WHERE FirstName LIKE [JT]im 可以找到三个字母的、以 im 结尾并以 J 或 T 开始的名字即仅有 Jim 和 Tim WHERE LastName LIKE m[^c]% 可以找到以 m 开始的、后面的第二个字母不为 c 的所有姓。 此处我们也选择使用 NOT 运算符若要找到所有名字不以 M 或 A 开始的员工我们可以编写以下语句 SELECT EmployeeID, FirstName, LastName, HireDate, City FROM Employees WHERE (FirstName NOT LIKE M%) AND (FirstName NOT LIKE A%) 结果如下 EmployeeID FirstName LastName HireDate City 1 Nancy Davolio 1/5/1992 12:00:00 Seattle 3 Janet Leverling 1/4/1992 12:00:00 Kirkland 5 Steven Buchanan 17/10/1993 12:00:00 London 7 Robert King 2/1/1994 12:00:00 London 8 Laura Callahan 5/3/1994 12:00:00 Seattle ORDER BY子句 直到现在我们一直在讨论筛选数据即定义一些条件来确定哪些行将包括在从数据库提取并返回的最终行集中。一旦我们确定了哪些列和行将包括在 SELECT 查询的结果中我们可能就希望控制这些行显示的顺序对数据排序。 若要对数据行排序我们需要 ORDER BY 子句。ORDER BY 子句包括了一个或多个用于指定排序顺序的列名。如果返回至第一批 SELECT 语句中的某条语句我们可以用以下语句按 City 对其结果排序 SELECT EmployeeID, FirstName, LastName, HireDate, City FROM Employees ORDER BY City 默认情况下列的排序顺序为升序从最小值到最大值上述查询的结果如下所示 EmployeeID FirstName LastName HireDate City 3 Janet Leverling 1/4/1992 12:00:00 Kirkland 5 Steven Buchanan 17/10/1993 12:00:00 London 6 Michael Suyama 17/10/1993 12:00:00 London 7 Robert King 2/1/1994 12:00:00 London 9 Anne Dodsworth 15/11/1994 12:00:00 London 4 Margaret Peacock 3/5/1993 12:00:00 Redmond 1 Nancy Davolio 1/5/1992 12:00:00 Seattle 8 Laura Callahan 5/3/1994 12:00:00 Seattle 2 Andrew Fuller 14/8/1992 12:00:00 Tacoma 如果我们希望列的排序顺序为降序我们可以在列名后包括 DESC 关键字。 ORDER BY 子句支持使用多列。您可以包括以逗号分隔的多个列以按其排序行将先按指定的第一列进行排序然后再按指定的下一列进行排序。如果我们向 SELECT 子句添加 Country 字段并希望按 Country 和 City 排序我们可以编写以下语句 SELECT EmployeeID, FirstName, LastName, HireDate, Country, City FROM Employees ORDER BY Country, City DESC 请注意为了使语句显得更有趣我们已经指定了 City 列的排序顺序为降序从最大值到最小值。Country 列的排序顺序仍为升序。为了更清楚地了解到这一点我们可以把语句编写为 SELECT EmployeeID, FirstName, LastName, HireDate, Country, City FROM Employees ORDER BY Country ASC, City DESC 但是默认情况下列的排序顺序为升序。所以加上ASC不是必要的并且很少这么做。此查询返回的结果如下所示 EmployeeID FirstName LastName HireDate Country City 5 Steven Buchanan 17/10/1993 12:00:00 UK London 6 Michael Suyama 17/10/1993 12:00:00 UK London 7 Robert King 2/1/1994 12:00:00 UK London 9 Anne Dodsworth 15/11/1994 12:00:00 UK London 2 Andrew Fuller 14/8/1992 12:00:00 USA Tacoma 1 Nancy Davolio 1/5/1992 12:00:00 USA Seattle 8 Laura Callahan 5/3/1994 12:00:00 USA Seattle 4 Margaret Peacock 3/5/1993 12:00:00 USA Redmond 3 Janet Leverling 1/4/1992 12:00:00 USA Kirkland 重要的是要注意要在 ORDER BY 子句中使用某一列时并不需要在选定的返回的多个列中包括这一列。如果我们不需要查看Country 值只是对于将其作为主排序字段感兴趣可以编写以下查询 SELECT EmployeeID, FirstName, LastName, HireDate, City FROM Employees ORDER BY Country ASC, City DESC 所得结果的排序顺序与上一个查询所得结果的排序顺序相同 EmployeeID FirstName LastName HireDate City 5 Steven Buchanan 17/10/1993 12:00:00 London 6 Michael Suyama 17/10/1993 12:00:00 London 7 Robert King 2/1/1994 12:00:00 London 9 Anne Dodsworth 15/11/1994 12:00:00 London 2 Andrew Fuller 14/8/1992 12:00:00 Tacoma 1 Nancy Davolio 1/5/1992 12:00:00 Seattle 8 Laura Callahan 5/3/1994 12:00:00 Seattle 4 Margaret Peacock 3/5/1993 12:00:00 Redmond 3 Janet Leverling 1/4/1992 12:00:00 Kirkland INSERT INTO语句 INSERT INTO语句用于新增一个记录。该语句的格式 INSERT INTO 表 [(字段1[,字段2[, ...]])] VALUES (值1[,值2[, ...]) 新增的记录将依照指定字段排列的顺序插入对应的值譬如值1将被插入至字段1值2将被插入至字段2依此类推。 若未指定 (字段1[,字段2[, ...]]) 将依照表所定义的字段排列的顺序插入对应的值在VALUES 子句必须包含表中的每一字段值。 值间须使用逗点分隔文字字段须使用单用引号 (值) 括起来。 例如向Employees表中插入一条记录。 INSERT INTO Employees (EmployeeID, FirstName, LastNameHireDate City , Country) VALUES (10, ‘Mary’ ‘Williams’,’15/4/1993 12:00:00’,’New York’,’USA’) Update语句 用途更新表中原有数据 语法Update table_name Set column_name new_value Where column_name some_value 例把EmployeeID为10的记录改为FirstName是BillLastName是ClintonHireDate是25/11/1994 12:00:00City是Los AngelesCountry不变还是USA UPDATE Employees SET FirstName Bill, LastName’Clinton’, HireDate’25/11/1994 12:00:00’,City Los Angeles WHERE EmployeeID10 好了SQL命令我们先介绍这几条下面我们通过例程ConnPtr_Open_Exe演示_ConnectionPtr的Open函数建立与数据源的连接并使用Execute()函数来执行SQL命令。 例程ConnPtr_Open_Exe 打开VC 6.0新建一个基于对话框的工程ConnPtr_Open_Exe。在对话框IDD_CONNPTR_OPEN_EXE_DIALOG中进行编辑 使用三个Group Box分成三个部分第一部分演示使用Execute()函数来执行INSERT INTO命令第二部分演示使用Execute()函数来执行Update命令第三部分演示使用Execute()函数来执行SELECT命令。其中第一部分和第二部分不需要返回记录集第三部分演示返回记录集显示结果。 该对话框几个控件如下 控件名称 ID 用途 按钮 IDC_BTN_INSERT_INTO 执行INSERT INTO语句 按钮 IDC_BTN_UPDATE 执行Update语句 按钮 IDC_BTN_SELECT 执行SELECT语句 列表框 IDC_LIST1 显示SELECT语句执行结果 使用ClassWizard给列表框IDC_LIST1创建CListBox变量m_list1 双击IDC_BTN_INSERT_INTO按钮并编辑OnBtnInsertInto()函数如下 void CConnPtr_Open_ExeDlg::OnBtnInsertInto() { _ConnectionPtr m_pConnection; _variant_t RecordsAffected; try { m_pConnection.CreateInstance(__uuidof(Connection)); m_pConnection-Open(ProviderMicrosoft.Jet.OLEDB.4.0;Data SourceNorthwind.mdb,,,adModeUnknown); } catch(_com_error e) { CString errormessage; errormessage.Format(连接数据库失败!\r错误信息:%s,e.ErrorMessage()); AfxMessageBox(errormessage); return; } try { _bstr_t strCmdINSERT INTO Employees(EmployeeID,FirstName,LastName,HireDate,City,Country) VALUES(10,Mary,Williams,15/4/1993 12:00:00,New York,USA); m_pConnection-Execute(strCmd,RecordsAffected,adCmdText); } catch(_com_error e) { AfxMessageBox(e.Description()); } if(m_pConnection-State) m_pConnection-Close(); } 双击IDC_BTN_UPDATE按钮并编辑OnBtnUpdate()函数如下 void CConnPtr_Open_ExeDlg::OnBtnUpdate() { _ConnectionPtr m_pConnection; _variant_t RecordsAffected; try { m_pConnection.CreateInstance(__uuidof(Connection)); m_pConnection-Open(ProviderMicrosoft.Jet.OLEDB.4.0;Data SourceNorthwind.mdb,,,adModeUnknown); } catch(_com_error e) { CString errormessage; errormessage.Format(连接数据库失败!\r错误信息:%s,e.ErrorMessage()); AfxMessageBox(errormessage); return; } try { _bstr_t strCmdUPDATE Employees SET FirstNameBill,LastNameClinton,HireDate25/11/1994 12:00:00,CityLos Angeles WHERE EmployeeID10; m_pConnection-Execute(strCmd,RecordsAffected,adCmdText); } catch(_com_error e) { AfxMessageBox(e.Description()); } if(m_pConnection-State) m_pConnection-Close(); } 双击IDC_BTN_SELECT按钮并编辑OnBtnSelect()函数如下 void CConnPtr_Open_ExeDlg::OnBtnSelect() { _ConnectionPtr m_pConnection; _variant_t RecordsAffected; _RecordsetPtr m_pRecordset; try { m_pConnection.CreateInstance(__uuidof(Connection)); m_pConnection-Open(ProviderMicrosoft.Jet.OLEDB.4.0;Data SourceNorthwind.mdb,,,adModeUnknown); } catch(_com_error e) { CString errormessage; errormessage.Format(连接数据库失败!\r错误信息:%s,e.ErrorMessage()); AfxMessageBox(errormessage); return; } try { m_pRecordset.CreateInstance(ADODB.Recordset); //为Recordset对象创建实例 _bstr_t strCmdSELECT EmployeeID,FirstName,LastName,HireDate,City FROM Employees WHERE CityLondon; m_pRecordsetm_pConnection-Execute(strCmd,RecordsAffected,adCmdText); } catch(_com_error e) { AfxMessageBox(e.Description()); } _variant_t vEmployeeID,vFirstName,vLastName,vHireDate,vCity; try { while(!m_pRecordset-adoEOF) { vEmployeeIDm_pRecordset-GetCollect(_variant_t((long)0)); //取得第1列的值从0开始计数你也可以直接列出列的名称如下一行 vFirstNamem_pRecordset-GetCollect(FirstName); vLastNamem_pRecordset-GetCollect(LastName); vHireDatem_pRecordset-GetCollect(HireDate); vCitym_pRecordset-GetCollect(City); CString strtemp; if(vEmployeeID.vt!VT_NULL) { strtemp.Format(%d,vEmployeeID.lVal); } if(vFirstName.vt!VT_NULL) { strtemp      ; strtemp(LPCTSTR)(_bstr_t)vFirstName; } if(vLastName.vt!VT_NULL) { strtemp      ; strtemp(LPCTSTR)(_bstr_t)vLastName; } if(vHireDate.vt!VT_NULL) { strtemp      ; strtemp(LPCTSTR)(_bstr_t)vHireDate; } if(vCity.vt!VT_NULL) { strtemp      ; strtemp(LPCTSTR)(_bstr_t)vCity; } m_list1.AddString(strtemp); m_list1.AddString(\n); m_pRecordset-MoveNext(); } } catch(_com_error e) { AfxMessageBox(e.Description()); } m_pRecordset-Close(); m_pRecordsetNULL; m_pConnection-Close(); m_pConnectionNULL; } 在stdafx.h中加入如下语句 #import C:\Program Files\Common Files\system\ado\msado15.dll rename(EOF,adoEOF) 在BOOL CConnPtr_Open_ExeApp::InitInstance()函数中加入 AfxOleInit(); 编译并运行该程序观察运行结果。点击IDC_BTN_INSERT_INTO按钮打开数据库Northwind.mdb的Employees表你就会发现增加了一条记录 10, Mary , Williams , 15/4/1993 12:00:00 , New York , USA 关闭数据库。 继续点击IDC_BTN_UPDATE按钮打开数据库Northwind.mdb的Employees表你就会发现第10条记录变为 10, Bill , Clinton , 25/11/1994 12:00:00 , Los Angeles, USA 关闭数据库。 继续点击IDC_BTN_SELECT按钮你就会发现列表框中会显示出City为London的记录如下 EmployeeID FirstName LastName HireDate City 5 Steven Buchanan 17/10/1993 12:00:00 London 6 Michael Suyama 17/10/1993 12:00:00 London 7 Robert King 2/1/1994 12:00:00 London 9 Anne Dodsworth 15/11/1994 12:00:00 London 该部分演示了如何使用_ConnectionPtr接口开发ACCESS数据库先创建一个Connection对象实例然后用Open方法打开一个库连接最后使用Execute方法执行SQL语句进行其它有关数据库的访问和操作。接下来的第五部分将演示使用使用_RecordsetPtr接口开发ACCESS数据库。 使用_RecordsetPtr接口开发ACCESS数据库 _RecordsetPtr智能指针它是专门为通过记录集操作数据库而设立的指针通过该接口可以对数据库的表内的记录、字段等进行各种操作。 要搞清楚:数据库和ADO的记录集是两个不同的概念, 是存在于不同物理位置的两个存储空间。 记录集相当于是实际数据的一份拷贝。 正因为记录集是相对脱离数据库而存在的, 所以才存在后面将要介绍的Open方法中涉及的光标类型和锁定类型这两个问题。 _RecordsetPtr接口的使用方法 先创建记录集对象 _ConnectionPtr m_pRecordset; m_pRecordset.CreateInstance(__uuidof(Recorset)); 创建记录集对象后只是为它分配内存空间记录集中不含任何数据。记录集对象是用来获得数据库中的数据并对其操作的所以还要打开记录集从数据库中取得数据记录。可有多种方法打开记录集下面只介绍最常用的Open方法 为记录集对象分配了空间后就可以用Open函数打开记录集该函数原型为 HRESULT Recordset15::Open(const _variant_t Source,const _variant_t ActiveConnection,enum CursorTypeEnum CursorType,enum LockTypeEnum LockType,long Options) 参数 Source是数据查询字符串。 ActiveConnection是已经建立好的连接我们需要用Connection对象指针来构造一个_variant_t对象。 CursorType 光标类型它是枚举CursorTypeEnum中的一个值。 LockType 锁定类型 它是枚举LockTypeEnum中的一个值 Options 指定Source的类型 光标类型CursorType可取如下值之一 adOpenUnspecified-1 不作特别指定adOpenForwardOnly0 默认值前滚静态光标。这种光标只能向前浏览记录集比如用MoveNext向前滚动这种方式可节省资源提高浏览速度但诸如BookMark、RecordCount、AbsolutePosition、AbsolutePage都不能使用。adOpenKeyset1 键集游标采用这种光标的记录集看不到其它用户的新增、删除操作但对于更新原有记录的操作对你是可见的。adOpenDynamic2 动态光标所有数据库的操作都会立即在用户记录集上反应出来。adOpenStatic3 静态游标。它为记录产生一个静态备份其他用户的新增、删除、更新操作对你的记录集来说是不可见的。 LockType锁定类型它可以是以下值之一请看如下枚举结构 enum LockTypeEnum { adLockUnspecified-1,    //未指定 adLockReadOnly1,          //只读记录集默认值。无法更改数据。 adLockPessimistic2,      //悲观锁定方式。只有在调用Update方法时才锁定记录。这是最安全的锁定机制 adLockOptimistc3,   //乐观锁定方式只有在你调用Update方法时才锁定记录。 在此之前仍然可以做数据的更新、插入、删除等操作 adLockBatchOptimistic4 //乐观分批更新。编辑时记录不会锁定更改、插入及删除是在批处理模式下完成。 } 关于光标和锁定类型对于一般用户建议您只作简单了解后面将进一步进行解说。 Options可以取如下值之一 adCmdText: 表明CommandText是文本命令。 adCmdTable:表明CommandText是一个表名。 adCmdProc:表明CommandText是一个存储过程。 adCmdUnknown:未知。 例如假设m_pConnection是我们已经建立好的连接我们使用_RecordsetPtr接口的Open方法打开Employees表的记录集的语句如下 m_pRecordset-Open(“SELECT * FROM Employees”, _variant_t((IDispatch*)m_pConnection,true), adOpenStatic, adLockOptimistic, adCmdText); 例程RecordsetPtr演示使用_RecordsetPtr指针通过记录集操作数据库。 打开VC 6.0新建一个基于对话框的工程RecordsetPtr。在对话框IDD_RECORDSETPTR_DIALOG中进行编辑 使用三个Group Box分成四个部分第一部分演示如何读取数据库数据第二部分演示如何修改数据库第三部分演示如何向数据库中插入数据第四部分演示如何删除数据库中的数据。 使用ClassWizard给列表框IDC_LIST1创建CListBox变量m_list1 双击IDC_BTN_READREC按钮并编辑OnBtnReadrec()函数如下 void CRecordsetPtrDlg::OnBtnReadrec() { _ConnectionPtr m_pConnection; _RecordsetPtr m_pRecordset; try { m_pConnection.CreateInstance(__uuidof(Connection)); m_pConnection-Open(ProviderMicrosoft.Jet.OLEDB.4.0;Data SourceNorthwind.mdb,,,adModeUnknown); } catch(_com_error e) { CString errormessage; errormessage.Format(连接数据库失败!\r错误信息:%s,e.ErrorMessage()); AfxMessageBox(errormessage); return; } try { m_pRecordset.CreateInstance(ADODB.Recordset); m_pRecordset-Open(SELECT EmployeeID,FirstName,LastName,HireDate,City FROM Employees WHERE CityLondon, _variant_t((IDispatch*)m_pConnection,true), adOpenStatic, adLockOptimistic, adCmdText); } catch(_com_error e) { AfxMessageBox(e.Description()); } _variant_t vEmployeeID,vFirstName,vLastName,vHireDate,vCity; try { while(!m_pRecordset-adoEOF) { vEmployeeIDm_pRecordset-GetCollect(_variant_t((long)0)); //取得第1列的值从0开始计数你也可以直接列出列的名称如下一行 vFirstNamem_pRecordset-GetCollect(FirstName); vLastNamem_pRecordset-GetCollect(LastName); vHireDatem_pRecordset-GetCollect(HireDate); vCitym_pRecordset-GetCollect(City); CString strtemp; if(vEmployeeID.vt!VT_NULL) { strtemp.Format(%d,vEmployeeID.lVal); } if(vFirstName.vt!VT_NULL) { strtemp      ; strtemp(LPCTSTR)(_bstr_t)vFirstName; } if(vLastName.vt!VT_NULL) { strtemp      ; strtemp(LPCTSTR)(_bstr_t)vLastName; } if(vHireDate.vt!VT_NULL) { strtemp      ; strtemp(LPCTSTR)(_bstr_t)vHireDate; } if(vCity.vt!VT_NULL) { strtemp      ; strtemp(LPCTSTR)(_bstr_t)vCity; } m_list1.AddString(strtemp); m_list1.AddString(\n); m_pRecordset-MoveNext(); } } catch(_com_error e) { AfxMessageBox(e.Description()); } m_pRecordset-Close(); m_pRecordsetNULL; m_pConnection-Close(); m_pConnectionNULL;  } 该段代码演示了如何读取数据库表内的数据。其原理是如果没有遇到表结束标志adoEOF则用GetCollect(字段名)来获取当前记录指针所指的字段值然后再用MoveNext()方法移动到下一条记录位置。 双击IDC_BTN_CHANGE按钮并编辑OnBtnChange()函数如下 void CRecordsetPtrDlg::OnBtnChange() { _ConnectionPtr m_pConnection; _RecordsetPtr m_pRecordset; try { m_pConnection.CreateInstance(__uuidof(Connection)); m_pConnection-Open(ProviderMicrosoft.Jet.OLEDB.4.0;Data SourceNorthwind.mdb,,,adModeUnknown); } catch(_com_error e) { CString errormessage; errormessage.Format(连接数据库失败!\r错误信息:%s,e.ErrorMessage()); AfxMessageBox(errormessage); return; } try { m_pRecordset.CreateInstance(ADODB.Recordset); m_pRecordset-Open(SELECT EmployeeID,FirstName,LastName,HireDate,City FROM Employees WHERE (CityLondon) AND (EmployeeID6), _variant_t((IDispatch*)m_pConnection,true), adOpenStatic, adLockOptimistic, adCmdText); } catch(_com_error e) { AfxMessageBox(e.Description()); } try { while(!m_pRecordset-adoEOF) { m_pRecordset-PutCollect(LastName,_variant_t(Jackson)); m_pRecordset-MoveNext(); } m_pRecordset-Update(); } catch(_com_error* e) { AfxMessageBox(e-ErrorMessage()); } m_pRecordset-Close(); m_pRecordsetNULL; m_pConnection-Close(); m_pConnectionNULL; } 该段代码演示了如何修改记录中的字段值 将记录指针移动到要修改记录的位置处直接用PutCollect(字段名值)将新值写入并Update()更新到数据库即可。 移动记录指针可以通过MoveFirst()方法移动到第一条记录MoveLast()方法移动到最后一条记录MovePrevious()方法移动到当前记录的前一条记录MoveNext()方法移动到当前记录的下一条记录。也可以使用Move(记录号)移动记录指针到需要位置。注意Move()方法是相对于当前记录来移动指针位置的。正值向后移动负值向前移动。如Move(3)当前记录是3时它将从记录3开始往后再移动3条记录位置。关于移动记录指针后面将会用到。 双击IDC_BTN_NEW按钮并编辑OnBtnNew()函数如下 void CRecordsetPtrDlg::OnBtnNew() { _ConnectionPtr m_pConnection; _RecordsetPtr m_pRecordset; try { m_pConnection.CreateInstance(__uuidof(Connection)); m_pConnection-Open(ProviderMicrosoft.Jet.OLEDB.4.0;Data SourceNorthwind.mdb,,,adModeUnknown); } catch(_com_error e) { CString errormessage; errormessage.Format(连接数据库失败!\r错误信息:%s,e.ErrorMessage()); AfxMessageBox(errormessage); return; } try { m_pRecordset.CreateInstance(ADODB.Recordset); m_pRecordset-Open(SELECT * FROM Employees, _variant_t((IDispatch*)m_pConnection,true), adOpenStatic, adLockOptimistic, adCmdText); } catch(_com_error e) { AfxMessageBox(e.Description()); } try { m_pRecordset-MoveLast(); m_pRecordset-AddNew(); m_pRecordset-PutCollect(EmployeeID,_variant_t((long)10)); m_pRecordset-PutCollect(FirstName,_variant_t(Mary)); m_pRecordset-PutCollect(LastName,_variant_t(Williams)); m_pRecordset-PutCollect(HireDate,_variant_t(15/4/1993 12:00:00)); m_pRecordset-PutCollect(City,_variant_t(New York)); m_pRecordset-PutCollect(Country,_variant_t(USA)); } catch(_com_error *e) { AfxMessageBox(e-ErrorMessage()); } m_pRecordset-Update(); m_pRecordset-Close(); m_pRecordsetNULL; m_pConnection-Close(); m_pConnectionNULL; } 该段代码演示如何插入记录 先用AddNew()方法新增一个空记录再用PutCollect(字段名值)输入每个字段的值最后用Update()更新到数据库即可。 双击IDC_BTN_DELETE按钮并编辑OnBtnDelete()函数如下 void CRecordsetPtrDlg::OnBtnDelete() { _ConnectionPtr m_pConnection; _RecordsetPtr m_pRecordset; try { m_pConnection.CreateInstance(__uuidof(Connection)); m_pConnection-Open(ProviderMicrosoft.Jet.OLEDB.4.0;Data SourceNorthwind.mdb,,,adModeUnknown); } catch(_com_error e) { CString errormessage; errormessage.Format(连接数据库失败!\r错误信息:%s,e.ErrorMessage()); AfxMessageBox(errormessage); return; } try { m_pRecordset.CreateInstance(ADODB.Recordset); m_pRecordset-Open(SELECT * FROM Employees, _variant_t((IDispatch*)m_pConnection,true), adOpenStatic, adLockOptimistic, adCmdText); } catch(_com_error e) { AfxMessageBox(e.Description()); } try { //假设删除第10条记录 m_pRecordset-MoveFirst(); m_pRecordset-Move(9); m_pRecordset-Delete(adAffectCurrent); //参数adAffectCurrent为删除当前记录 m_pRecordset-Update(); } catch(_com_error *e) { AfxMessageBox(e-ErrorMessage()); } m_pRecordset-Close(); m_pRecordsetNULL; m_pConnection-Close(); m_pConnectionNULL;  } 该段代码演示了如何删除记录 先将记录指针移动到要删除的记录的位置直接用Delete()方法删除它并用Update()来更新数据库即可。 使用记录集操作完毕后要关闭记录集 直接用Close()方法关闭记录集并赋予其空值。代码如下 m_pRecordset-Close(); m_pConnection-Close(); m_pRecordsetNULL; m_pConnectionNULL; 使用_RecordsetPtr接口开发ACCESS数据库就介绍到这里它可以更加灵活地操作数据库。当然您还可以使用_CommandPtr接口开发ACCESS数据库它提供了一个简单的方法来执行返回记录集的SQL语句。本文不讲解_CommandPtr接口。 用心的读者您可能已经发现使用Connection对象的Execute方法可以完成数据库的操作使用Recordset也可以完成同样功能的数据库操作。我们应该采用哪种方法呢另外Connection对象的Execute方法返回一个记录集Recordset的Open方法也打开一个记录集二者有什么区别呢下面我们将进行说明。 前面已经讲过数据库和ADO的记录集是两个不同的概念是存在于不同物理位置的两个存储空间。记录集相当于是实际数据的一份拷贝。正因为记录集是相对脱离数据库而存在的所以才光标类型和锁定类型这两个问题。 在记录集被创建以后数据提供者负责在数据库和记录集之间进行侦测记录集的类型決定了提供者在多大程度上确保数据库与记录集之间的一致性这通常是由光标类型決定的而同时也決定了提供者采取什么方式来确保用戶在更新数据库时本次更新的完整性这是由锁类型決定的。 比方说一个用户正在对一个记录集做一次更新并试图将此更新应用到数据库中。因为通过记录集来更新数据是分两步完成的第一步是修改记录集的內容第二步才是将修改通过数据提供者更新到数据库中两步之间存在时间上的细微差別所以他可能会遇到一个问题即他的第一步到第二步的操作是否会因为这期间同时遇到其他用户的操作而失败。 对数据库的部分记录进行锁定解決了这个问题而不同类型的锁解決问题的方式也不一样。有的在第一步开始时就锁定数据库有的在第二步开始时才锁定数据库。锁定占用了数据库资源而使得记录集在对于使用者的更新操作方面更加可靠。 综上所述可以得出一个结论锁是由于记录集的存在而存在的沒有记录集或者說沒有可供更新的记录集,锁就沒有存在的意义。 从效率上考虑,锁会降低并发性尤其是当同时连接数据库的用户增多时不采用记录集来更新数据库总是更好的选择虽然使用起来会更麻烦一些。 选择与数据库联系得较少的记录集总是能提高效率因为提供者无需做很多的侦测工作。比如动态的记录集总是实时地将数据库的状态反映到记录集中这很有用但也会耗费无提供者更多的精力。如果无需更新数据只读的记录集是与数据库联系得最少的一种选择使用这种记录集来代替其它类型在效率上通常会有很明显的提高。 Connection对象的Execute方法只能得到一个只能前移的、只读的记录集。 使用RecordAffected参数找出有多少条记录受到影响。一旦Execute命令执行完毕受SQL命令影响的记录数就返回到RecordAffected参数中。 Connection的Execute方法不支持任何锁定类型这就是和Recordset的Open方法的主要区别所在所以用Recordset的Open方法将更灵活而Connection的Execute方法更简洁高效。 Execute是Connection对象对数据库操作的一个方法你可以把它理解为执行SQL语句也就是说Execute是一个操作方法而不是像open方法返回一个记录集然后再对记录集操作。 尽量使用SQL语句进行数据库操作。尽管采用Recordset对象来更新数据是非常方便的但是它的开销也更大所以如果可能的话就要采用SQL语句来更新数据。 Execute返回的记录集是只读的不可以更新所以也就不存在锁。这个记录集不具备Recordset可以改变光标类型和锁定类型的功能它只能返回一个只能前移的、只读的记录集。 尽管很多开发人员都习惯采用“SELECT * FROM 表名”的模式进行查询但是为了提高系统的效率如果你只需要其中某几个字段值的话最好把这几个字段直接写出来同时需要限定返回记录集的范围通过WHERE子句进行限定。
http://www.dnsts.com.cn/news/120647.html

相关文章:

  • 免费制作网站app校园网上零售网站建设方案
  • 建网站的公司叫什么太原seo排名公司
  • c2c的电子商务网站有哪些重庆綦江网站制作公司推荐
  • 江西网站做的好的企业文化建设主题网站的顺序是什么意思
  • 广东网站推广公司网站开发模块学些什么软件
  • 郑州外贸网站建设公司价格dede网站后台设置wap模板目录
  • 智慧景区网站服务建设wordpress 视频 去广告插件下载
  • Wordpress网站能做seo吗门户网站建设的作用及意义
  • 公司网站做好了还需石家庄经济
  • 房屋中介做网站的网站建设公司华网天下北京
  • 东莞网站建设总结网站建设美橙
  • 企业网站的建设内容流量网站建设教程
  • 百度怎么做开锁网站嵌入式开发培训机构排名
  • 一键做单页网站百度极速版下载
  • 汕头有建网站公司吗手机系统优化
  • 怎么创建网站免费的自己的电脑做网站服务器吗
  • 建站的费用哪家网站推广好
  • 建设多语种网站wordpress的密码忘记
  • 导航网站 cmsphp建站平台
  • 本地南京网站建设沙井网站推广
  • 做外贸网站要有域名信息大全
  • 个人可以做几个网站网站建设做的好
  • 招投标网站建设开发怎么样才算是一个网站页面
  • 下载类网站 前置备案设计师联盟网站
  • 深圳做微商网站设计微网站的价格
  • 中国建设报社网站网站建设方案书 人员安排
  • 官网建站合作模版优化关键词可以选择哪个工具
  • 手机怎么做电子书下载网站自己建网址
  • 盖县网站开发网站建设服务器篇
  • 怎么用虚拟主机做网站步骤网站怎样推广 优帮云