分享

转贴:VC++6.0下使用ADO技术访问SQL 数据库

 mcqlzz 2010-09-13
VC++6.0下使用ADO技术访问SQL 数据库

*********************************************************************************************
1. ADOConn功能类的引入
*********************************************************************************************
// ADOConn.h: interface for the ADOConn class.
//
//////////////////////////////////////////////////////////////////////
#import "c:\Program Files\Common Files\System\ado\msado15.dll" no_namespace rename("EOF","adoEOF") rename("BOF","adoBOF")
#if !defined(AFX_ADOCONN_H__20D9D06A_E099_4B1C_99DD_5B1F11B3A313__INCLUDED_)
#define AFX_ADOCONN_H__20D9D06A_E099_4B1C_99DD_5B1F11B3A313__INCLUDED_

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000

class ADOConn
{

public:
_ConnectionPtr m_pConnection;
_RecordsetPtr m_pRecordset;
public:
ADOConn();
virtual ~ADOConn();
void OnInitADOConn();
_RecordsetPtr& GetRecordSet(_bstr_t bstrSQL);
BOOL ExecuteSQL(_bstr_t bstrSQL);
void ExitConnect();
};

#endif // !defined(AFX_ADOCONN_H__20D9D06A_E099_4B1C_99DD_5B1F11B3A313__INCLUDED_)
--------------------------------------------------------------------------------------------
// ADOConn.cpp: implementation of the ADOConn class.
//数据库连接、读记录及断开操作
//////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "CheckMan.h"
#include "ADOConn.h"

#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

ADOConn::ADOConn()
{
}

ADOConn::~ADOConn()
{
}

//初始化——连接数据库
void ADOConn::OnInitADOConn()
{
// 初始化OLE/COM库环境
::CoInitialize(NULL);  
try
{
   // 创建Connection对象
   m_pConnection.CreateInstance("ADODB.Connection");
   // 设置连接字符串,必须是BSTR型或者_bstr_t类型
   _bstr_t strConnect = "Provider=SQLOLEDB;Server=127.0.0.1;Database=basename;uid=sa;pwd=pwd;";
   m_pConnection->Open(strConnect,"","",adModeUnknown);
}
// 捕捉异常
catch(_com_error e)
{
   AfxMessageBox("数据库连接失败,请开启数据库服务!");
     PostQuitMessage(0);
   //AfxMessageBox(e.Description());
}
}

// 执行查询
_RecordsetPtr& ADOConn::GetRecordSet(_bstr_t bstrSQL)
{
try
{
   // 连接数据库,如果Connection对象为空,则重新连接数据库
   if(m_pConnection==NULL)
     OnInitADOConn();
   // 创建记录集对象
   m_pRecordset.CreateInstance(__uuidof(Recordset));
   // 取得表中的记录
   m_pRecordset->Open(bstrSQL,m_pConnection.GetInterfacePtr(),adOpenDynamic,adLockOptimistic,adCmdText);
}
// 捕捉异常
catch(_com_error e)
{
   AfxMessageBox("数据库记录读取失败!");
     PostQuitMessage(0);
   // 显示错误信息
   //AfxMessageBox(e.Description());
}
// 返回记录集
return m_pRecordset;
}

// 执行SQL语句,Insert Update _variant_t
BOOL ADOConn::ExecuteSQL(_bstr_t bstrSQL)
{
try
{
   // 是否已经连接数据库
   if(m_pConnection==NULL)
     OnInitADOConn();
   // Connection对象的Execute方法:(_bstr_t CommandText,
   // VARIANT * RecordsAffected, long Options )
   // 其中CommandText是命令字串,通常是SQL命令。
   // 参数RecordsAffected是操作完成后所影响的行数,
   // 参数Options表示CommandText的类型:adCmdText-文本命令;adCmdTable-表名
   // adCmdProc-存储过程;adCmdUnknown-未知
   m_pConnection->Execute(bstrSQL,NULL,adCmdText);
   return true;
}
catch(_com_error e)
{
   AfxMessageBox("数据库SQL语句执行失败!");
     PostQuitMessage(0);
   //AfxMessageBox(e.Description());
   return false;
}
}

void ADOConn::ExitConnect()
{
// 关闭记录集和连接
if(m_pRecordset!=NULL)
   m_pRecordset->Close();
m_pConnection->Close();
// 释放环境
::CoUninitialize();
}

*********************************************************************************************
2. 建立数据库中表对应的表类,将表中的各个要操作的列都以变量的形式在类中再现,注意要保证对应的数据结构相通,例如SQL server中的 char n 类型对应VC++中的CString类型等。然后建立要操作的功能对应的功能函数,如sql_select(),sql_insert() 等等。
*********************************************************************************************
--------------------------------------------------------------------------------------------
2.1 INSERT 插入
--------------------------------------------------------------------------------------------
void Ctable::sql_insert()
{
ADOConn m_AdoConn;
m_AdoConn.OnInitADOConn();
_bstr_t vSQL;
//将各非字符串的数据转换为字符串
CString str_vlong,str_vint,str_vfloat;
str_tjxh.Format("%ld",tjxh);
str_yetl.Format("%d",yetl);
str_jzsly.Format("%f",jzsly);
//插入信息
vSQL="INSERT INTO table(lint,llong,lfloat,lstring,lchar)VALUES ("+vint+","+vlong+","+vfloat+",'"+vstring+"','"+vchar+"')";   //attention! 字符串的书写,见后面说明
m_AdoConn.ExecuteSQL(vSQL);
m_AdoConn.ExitConnect();
MessageBox(NULL,"保存体检信息成功!" , "提示", 0);

}
--------------------------------------------------------------------------------------------
2.2 SELECT查询
--------------------------------------------------------------------------------------------
void Ctable::sql_select(CString str)
{
   ADOConn m_AdoConn;
   m_AdoConn.OnInitADOConn();
   _bstr_t vSQL;
   vSQL = "SELECT * FROM table WHERE list="+str;   //不用对str加''
   _RecordsetPtr m_pRecordset;
   m_pRecordset=m_AdoConn.GetRecordSet(vSQL);
   if(m_pRecordset->adoEOF==1)
   AfxMessageBox("无法找到该数据记录!" );
   else      
{
   vint=atoi((_bstr_t)m_pRecordset->GetCollect("lint"));   //int 型读取
        tjxh=atol((_bstr_t)m_pRecordset->GetCollect("tjxh"));   //long 型读取
   lysly=atof((_bstr_t)m_pRecordset->GetCollect("yk_lysly"));// float 型读取
        ch=*(char*)((_bstr_t)m_pRecordset->GetCollect("ch")); //char 读取
        str=(LPCTSTR)(_bstr_t)m_pRecordset->GetCollect("str"); //char n,varchar n,string 的读取          
}
m_AdoConn.ExitConnect();
}
--------------------------------------------------------------------------------------------
2.3 UPDATE 更新
--------------------------------------------------------------------------------------------
void Ctable::sql_update()
{
ADOConn m_AdoConn;
m_AdoConn.OnInitADOConn();
_bstr_t vSQL;

//将各非字符串的数据转换为字符串
CString str_vlong,str_vint,str_vfloat;
str_vlong.Format("%ld",vlong);
str_vint.Format("%d",vint);
str_vfloat.Format("%f",vfloat);
//更新数据,注意第一个加号不可以是char
vSQL= "UPDATE table SET lstring='"+vstring+"',lchar ='" +vchar+"',lint=" +str_vint+ ","lfloat=" +str_vfloat+    "WHERE list='" +list+ "' ";
m_AdoConn.ExecuteSQL(vSQL);
m_AdoConn.ExitConnect();
MessageBox(NULL,"更新记录成功!" , "提示", 0);
}
--------------------------------------------------------------------------------------------
2.4 DELETE 删除
--------------------------------------------------------------------------------------------
void Ctable::sql_delete(CString str)
{
//连接数据库
ADOConn m_AdoConn;
m_AdoConn.OnInitADOConn();
_bstr_t vSQL;

//设置DELETE语句
vSQL = "DELETE FROM hit3D WHERE list='"+str+"' ";
//执行DELETE语句
m_AdoConn.ExecuteSQL(vSQL);

//断开与数据库的连接
m_AdoConn.ExitConnect();

}

*********************************************************************************
3. ADO控件的使用
*********************************************************************************
--------------------------------------------------------------------------------
3.1 ADO Data 控件
--------------------------------------------------------------------------------
1. 通过 VC 中 project-Add to Project/Components and controls,打开,找到Registered ActiveX Controls/Microsoft ADO Data

Control,version 6.0(OLEDB),加入;
2. 控件属性的设置
(1) 通过build命令生成连接字符串;如:Provider=SQLOLEDB.1;Password=happy;Persist Security Info=True;User ID=sa;Initial

Catalog=Lottery;Data Source=127.0.0.1
(2) 通过RecordSource的设置完成记录集的生成,如:使用1.adcmd text 形式,SELECT * FROM result3D ORDER BY xuhao DESC
(3) 设置密码等。
3. 注意一般将数据源设置为Data Source=127.0.0.1,即为本机的数据源。
4. 可以通过加入Cadodc型的变量m_adodc来设置高级属性,并且可以通过不同的SQL语言来返回要求的记录集。
通过它一般是从数据库中获取数据记录集,但是要把记录集进行显示或其它操作就要通过其它的控件。
--------------------------------------------------------------------------------
3.2 DataGrid 控件
--------------------------------------------------------------------------------
1. 通过 VC 中 project-Add to Project/Components and controls,打开,找到Registered ActiveX Controls/Microsoft DataGrid

Control,version 6.0(OLEDB),加入;
2. 控件属性的设置
可以直接通过ALL中进行设置,如各种权限的设置等,数据来源设为同时引入的ADO Data控件的数据记录集。
3. 通过CDataGrid型的变量m_datagrid来设置显示的其它属性,如:
_variant_t vIndex;
vIndex=long(0);    //0 为列号
m_datagrid.GetColumns().GetItem(vIndex).SetCaption("期号"); //设置标头文字
m_datagrid.GetColumns().GetItem(vIndex).SetWidth(45);   //设置列宽度
要先加入
#include "column.h"
#include "columns.h"
#include "COMDEF.H"
三个头文件。

4. 通过m_datagrid.GetItem(0)等命令来获取当前选中的记录内容。
DataGrid 控件一般用来显示多条记录的详细内容
--------------------------------------------------------------------------------
3.3 DataList 控件和DataCombo 控件
--------------------------------------------------------------------------------
1. 通过 VC 中 project-Add to Project/Components and controls,打开,找到Registered ActiveX Controls中相关内容,加入;
2. 设置属性,相差内容相同;
3. 要注意它们的使用都是要配合一个ADO DATA控件返回的数据记录集才可以完成的。

***********************************************************************************
4. VC++ 6.0 + SQL server的开发中的问题总结
***********************************************************************************

----------------------------------------------------------------------------------
4.1 vSQL字符串的书写
----------------------------------------------------------------------------------

在使用ADO技术进行数据库的访问时需要通过vSQL的字符串来进行相关功能的实现要注意到的是
vSQL是相当于一种CString类型的,所有在对它进行生成时要用到 +

如str="INSERT INTO record3D(number,xuhao,a,b,c)VALUES('"+number+"',"+str_xuhao+")" 一句其实是几个字符串连加在一起,分解如下:
str1= " INSERT INTO record3D(number,xuhao,a,b,c)VALUES(' "
str2= number
str3="',"
str4=str_xuhao
str5= ")"

str=str1+str2+str3+str4+str5;

另外各种数据类型要根据SQL语句的要求或需要' '或不需要' '的设置。

----------------------------------------------------------------------------------
4.2 SQL server中数据库表名和列名的约束
----------------------------------------------------------------------------------

有的时候好像SQL语句的书写是没有任何错误的,但是就是会报错提示 无法执行执行数据库语句,这时候就应该从数据库的方面来找原因了,

在设置数据库中表名和列名时一定要应该不能使用SQL server本身拥有的系统约束名,例如:

表名不能以数字开头,不能使用user,no,time等
列名不能用: user,no,time等
等等。
在使用了约束名之后,系统并不会报错,可是它会给你定义的名称加以修改,通常是加上一对[],例如会将你的no列名改成:[no],这样你在访

问的时候就一定要使用[no]做为列名才能够找到此列,不然就无法进行SQL语句的执行了。

----------------------------------------------------------------------------------
4.3 各种数据类型的转换
----------------------------------------------------------------------------------

1. CString ----> char*
p_str=(LPSTR)(LPCTSTR)str_CString;
2. CString ----> char[]
strcpy(str_char,(LPSTR)(LPCTSTR)str_CString);
3. CString、char[]、char*----> int
v_int=atoi((LPSTR)(LPCTSTR)str_CString);
v_int=atoi(str_CString);
4. CString、char[]、char*----> long
v_long=atol((LPSTR)(LPCTSTR)str_CString);
v_long=atol(str_CString);
5. char* ----> _bstr_t
_bstr_t str_bstr=p_str;
6. int ---> CString
str_CString.Format("%d",v_int);
7. long ---> CString
str_CString.Format("%ld",v_int);

----------------------------------------------------------------------------------
4.4 SQL删除一个表中所有记录命令
----------------------------------------------------------------------------------

删除表中的所有行,而不记录单个行删除操作。
语法
TRUNCATE TABLE name
参数
name
是要截断的表的名称或要删除其全部行的表的名称。
注释
TRUNCATE TABLE 在功能上与不带 WHERE 子句的 DELETE 语句相同:二者均删除表中的全部行。但 TRUNCATE TABLE 比 DELETE 速度快,且使

用的系统和事务日志资源少。
DELETE 语句每次删除一行,并在事务日志中为所删除的每行记录一项。TRUNCATE TABLE 通过释放存储表数据所用的数据页来删除数据,并且

只在事务日志中记录页的释放。
TRUNCATE TABLE 删除表中的所有行,但表结构及其列、约束、索引等保持不变。新行标识所用的计数值重置为该列的种子。如果想保留标识计

数值,请改用 DELETE。如果要删除表定义及其数据,请使用 DROP TABLE 语句。
对于由 FOREIGN KEY 约束引用的表,不能使用 TRUNCATE TABLE,而应使用不带 WHERE 子句的 DELETE 语句。由于 TRUNCATE TABLE 不记录在

日志中,所以它不能激活触发器。
TRUNCATE TABLE 不能用于参与了索引视图的表。

----------------------------------------------------------------------------------
4.5 UpdateData()
----------------------------------------------------------------------------------

UpdateData(FALSE) 是将数据从 变量 传送到 控件中;
UpdateData(TRUE) 是将数据从 控件 传送到 变量中;

----------------------------------------------------------------------------------
4.6 VC++ 6.0 工程中的类查看中看不到存在的类
----------------------------------------------------------------------------------

有两种方法解决问题:
1.在工程目录下把消失的类对应的头文件和源码文件都移出文件夹,然后打到工程,在类向导中选择该类,这时会提示找不到相应的文件,那

么这时再把类的两个文件拷入工程文件夹,然后在类向导中通过找到两个文件再建立这个类,这时在类查看中就会出现这个类了。

2.要删除工程目录下:project.clw 文件,然后打开工程,选 查看-建立类向导,这时会提示说有问题,那么就从文件中再全部导入类,一般

情况下会解决问题。

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多