哪位仁兄有c++联接、处理sql server的例子,不胜感激,可以另开贴给分!!!!

glhorse 2003-02-20 09:16:14
哪位仁兄有c++联接、处理sql server的例子,不胜感激,可以另开贴给分!!!!
...全文
100 8 打赏 收藏 转发到动态 举报
写回复
用AI写文章
8 条回复
切换为时间正序
请发表友善的回复…
发表回复
glhorse 2003-02-21
  • 打赏
  • 举报
回复
感谢大家,请继续阿
nik_Amis 2003-02-21
  • 打赏
  • 举报
回复
up
dwei 2003-02-21
  • 打赏
  • 举报
回复
不错,参考!

安装SQL Server时,选取开发文档后,
不就有很多例子么,可以借鉴阿。

^_^
happydreamer 2003-02-20
  • 打赏
  • 举报
回复
在VC中使用ADO开发数据库应用程序
一、ADO概述
ADO是Microsoft为最新和最强大的数据访问范例 OLE DB 而设计的,是一个便于使用的应用程序层接口。ADO 使您能够编写应用程序以通过 OLE.DB 提供者访问和操作数据库服务器中的数据。ADO 最主要的优点是易于使用、速度快、内存支出少和磁盘遗迹小。ADO 在关键的应用方案中使用最少的网络流量,并且在前端和数据源之间使用最少的层数,所有这些都是为了提供轻量、高性能的接口。之所以称为 ADO,是用了一个比较熟悉的暗喻,OLE 自动化接口。

OLE DB是一组”组件对象模型”(COM) 接口,是新的数据库低层接口,它封装了ODBC的功能,并以统一的方式访问存储在不同信息源中的数据。OLE DB是Microsoft UDA(Universal Data Access)策略的技术基础。OLE DB 为任何数据源提供了高性能的访问,这些数据源包括关系和非关系数据库、电子邮件和文件系统、文本和图形、自定义业务对象等等。也就是说,OLE DB 并不局限于 ISAM、Jet 甚至关系数据源,它能够处理任何类型的数据,而不考虑它们的格式和存储方法。在实际应用中,这种多样性意味着可以访问驻留在 Excel 电子数据表、文本文件、电子邮件/目录服务甚至邮件服务器,诸如 Microsoft Exchange 中的数据。但是,OLE DB 应用程序编程接口的目的是为各种应用程序提供最佳的功能,它并不符合简单化的要求。您需要的API 应该是一座连接应用程序和 OLE DB 的桥梁,这就是 ActiveX Data Objects (ADO)。

二、在VC中使用ADO
1、引入ADO库文件
使用ADO前必须在工程的stdafx.h文件里用直接引入符号#import引入ADO库文件,以使编译器能正确编译。代码如下所示:

代码1:用#import引入ADO库文件

#import "c:\program files\common files\system\ado\msado15.dll"

no_namespaces rename("EOF" adoEOF")

这行语句声明在工程中使用ADO,但不使用ADO的名字空间,并且为了避免常数冲突,将常数EOF改名为adoEOF。现在不需添加另外的头文件,就可以使用ADO接口了。

2、初始化OLE/COM库环境
必须注意的是,ADO库是一组COM动态库,这意味应用程序在调用ADO前,必须初始化OLE/COM库环境。在MFC应用程序里,一个比较好的方法是在应用程序主类的InitInstance成员函数里初始化OLE/COM库环境。

代码2:初始化OLE/COM库环境

BOOL CADOApp::InitInstance()
{
if(!AfxOleInit())
{

AfxMessageBox(“OLE初始化出错!”);

return FALSE;

}

……

}

函数AfxOleInit在每次应用程序启动时初始化OLE/COM库环境。

同DAO和CDatabase一样,ADO由几个接口组成:

_ConnectionPtr,_CommandPtr和_RecordsetPtr.

不同于DAO和Cdatabase的是,ADO基于COM的接口,因此,假如你没有接触过COM,你应该在使用ADO前先找有关书籍了解一下COM。

3、ADO接口简介
ADO库包含三个基本接口:_ConnectionPtr接口、_CommandPtr接口和_RecordsetPtr接口。

_ConnectionPtr接口返回一个记录集或一个空指针。通常使用它来创建一个数据连接或执行一条不返回任何结果的SQL语句,如一个存储过程。使用_ConnectionPtr接口返回一个记录集不是一个好的使用方法。通常同CDatabase一样,使用它创建一个数据连接,然后使用其它对象执行数据输入输出操作。

_CommandPtr接口返回一个记录集。它提供了一种简单的方法来执行返回记录集的存储过程和SQL语句。在使用_CommandPtr接口时,你可以利用全局_ConnectionPtr接口,也可以在_CommandPtr接口里直接使用连接串。如果你只执行一次或几次数据访问操作,后者是比较好的选择。但如果你要频繁访问数据库,并要返回很多记录集,那么,你应该使用全局_ConnectionPtr接口创建一个数据连接,然后使用_CommandPtr接口执行存储过程和SQL语句。

_RecordsetPtr是一个记录集对象。与以上两种对象相比,它对记录集提供了更多的控制功能,如记录锁定,游标控制等。同_CommandPtr接口一样,它不一定要使用一个已经创建的数据连接,可以用一个连接串代替连接指针赋给_RecordsetPtr的connection成员变量,让它自己创建数据连接。如果你要使用多个记录集,最好的方法是同Command对象一样使用已经创建了数据连接的全局_ConnectionPtr接口,然后使用_RecordsetPtr执行存储过程和SQL语句。
4、使用_ConnectionPtr接口
_ConnectionPtr是一个连接接口,它类似于CDatabase和CDaoDatabase。它们的工作原理相似。首先创建一个_ConnectionPtr接口实例,接着指向并打开一个ODBC数据源或OLE DB数据提供者(Provider)。以下代码和CDaoDatabase分别创建一个基于DSN和非DSN的数据连接。

代码3:使用CDaoDatabase(基于DSN)

CDaoDatabase MyDb = new CDaoDatabase();

MyDb.Open(NULL,FALSE,FALSE,"ODBC;DSN=samp;UID=admin;PWD=admin");
 

代码4:使用CDaoDatabase(基于非DSN)

CDaoDatabase MyDb = new CDaoDatabase();

MyDb.Open(NULL,FALSE,FALSE,"ODBC;DRIVER={SQL Server};SERVER=server;

DATABASE=samp;UID=admin;PWD=admin");

 
代码5:使用_ConnectionPtr(基于DSN)

_ConnectionPtr MyDb;

MyDb.CreateInstance(__uuidof(Connection));

MyDb->Open("DSN=samp;UID=admin;PWD=admin","","",-1);

 
代码6:使用_ConnectionPtr (基于非DSN)

_ConnectionPtr MyDb;

MyDb.CreateInstance(__uuidof(Connection));

MyDb->Open("Provider=SQLOLEDB;SERVER=server;DATABASE=samp;UID=admin;
PWD=admin","","",-1);

5、使用_RecordsetPtr接口
RecordsetPtr接口的使用方法和CDaoDatabase类似,通过以下代码的比较,你会发现使用_RecordsetPtr接口非常简单(以下代码使用上面已经创建的数据连接):
代码7:使用CDaoDatabase执行SQL语句

CDaoRecordset MySet = new CDaoRecordset(MyDb);

MySet->Open(AFX_DAO_USE_DEFAULT_TYPE,"SELECT * FROM t_samp");

Now using ADO:

 
代码8:使用_RecordsetPtr执行SQL语句

_RecordsetPtr MySet;

MySet.CreateInstance(__uuidof(Recordset));

MySet->Open("SELECT * FROM some_table",

MyDb.GetInterfacePtr(),adOpenDynamic,adLockOptimistic,adCmdText);

现在我们已经有了一个数据连接和一个记录集,接下来就可以使用数据了。从以下代码可以看到,使用ADO的_RecordsetPtr接口,就不需要象DAO那样频繁地使用大而复杂的数据结构VARIANT,并强制转换各种数据类型了,这也是ADO的优点之一。假定程序有一个名称为m_List的的ListBox控件,下面代码我们用_RecordsetPtr接口获取记录集数据并填充这个ListBox控件:
 
代码9:使用DAO访问数据

VARIANT * vFieldValue;

COleVariant covFieldValue;

CString Holder;

while(!MySet->IsEOF())
{

MySet->GetFieldValue("FIELD_1", covFieldValue);

vFieldValue = (LPVARIANT)covFieldValue;

if(vFieldValue->vt!-VT_NULL)

{

Holder.Format("%s",vFieldValue->pbVal);

m_List.AddString(Holder);

  }

MySet.MoveNext();
 
}

代码10:使用ADO访问数据

_variant_t Holder

try{

while(!MySet->adoEOF)

{
Holder = MySet->GetCollect("FIELD_1");

if(Holder.vt!=VT_NULL)

m_List.AddString((char*)_bstr_t(Holder));

MySet->MoveNext();

}

}

catch(_com_error * e)

{

CString Error = e->ErrorMessage();

AfxMessageBox(e->ErrorMessage());

}

catch(...)

{
MessageBox("ADO发生错误!");

}

必须始终在代码中用try和catch来捕获ADO错误,否则ADO错误会使你的应用程序崩溃。当ADO发生运行时错误时(如数据库不存在),OLE DB数据提供者将自动创建一个_com_error对象,并将有关错误信息填充到这个对象的成员变量.

 
6、使用_CommandPtr接口
_CommandPtr接口返回一个Recordset对象,并且提供了更多的记录集控制功能,以下代码示例了使用_CommandPtr接口的方法:

代码11:使用_CommandPtr接口获取数据

_CommandPtr pCommand;

_RecordsetPtr MySet;

pCommand.CreateInstance(__uuidof(Command));

pCommand->ActiveConnection=MyDb;

pCommand->CommandText="select * from some_table";

pCommand->CommandType=adCmdText;

pCommand->Parameters->Refresh();

MySet=pCommand->Execute(NULL,NULL,adCmdUnknown);

_variant_t TheValue = MySet->GetCollect("FIELD_1");

CString sValue=(char*)_bstr_t(TheValue);

7、关于数据类型转换
由于COM对象是跨平台的,它使用了一种通用的方法来处理各种类型的数据,因此CString 类和COM对象是不兼容的,我们需要一组API来转换COM对象和C++类型的数据。_vatiant_t和_bstr_t就是这样两种对象。它们提供了通用的方法转换COM对象和C++类型的数据。

8、小结
数据访问发展的趋势是OLE DB.使用OLE DB最简单的方法是ADO.ADO的对象层次模型封装了数据库访问细节,为C++程序员提供了一种非常好的数据访问策略。
happydreamer 2003-02-20
  • 打赏
  • 举报
回复
ODBC数据库访问方法及其VC实现要点

在应用程序中,往往需要数据库的支持,以统一管理和维护数据,同时可以提供高效地对数据进行排序、检索、查询等功能。但是数据库的访问方式比较多,实现方法也很多,且有很多编程注意事项。因此,正确理解数据库访问的方式、程序结构及相关的编程技巧是很重要的。本文将就这几个方面进行介绍。
1.ODBC数据库访问结构
通过ODBC访问数据库的结构如图1所示。


图1 ODBC数据库访问结构

ODBC是通过使用驱动程序(Driver)来实现应用程序对数据库的独立性的。各个模块的功能分别是:
● ODBC应用程序通过ODBC函数向数据库发送SQL语句并处理返回结果
● ODBC驱动程序管理器负责管理和装载特定的驱动程序
● ODBC驱动程序负责处理ODBC函数调用,提交SQL请求给特定的数据源并返回结果给应用程序。
● 数据源指要存取的数据及其相关的操作系统、数据库管理系统和网络系统。

2.VC++数据库应用程序结构
典型的VC++数据库应用程序的结构如图2所示。


图2 VC++数据库应用程序结构

下面详述各个模块之间的关系:
1) 数据源与记录集
在VC的MFC类库中,提供了数据源类(CDatabase)来实现对数据源的一个连接,又提供了记录集类(CRecordset)来管理数据源中选定的记录集合。开发时要从MFC的CRecordset类继承出自己的记录集类。
数据源对象与程序中的记录集对象关联在一起,通过在程序中操纵记录集对象来实现对数据源的访问。在记录集对象中维护着数据源中被访问的当前记录,通过Move之类的函数(如CRecordset::MoveFirst,CRecordset::MoveNext)可以改变当前记录,从而实现对整个数据源的访问。
数据源与记录集之间的信息交换是通过“记录域交换”(RFX)机制来实现的,如CRecordset:: DoFieldExchange。这个信息交换操作会由打开记录集、重新检索数据源和更新数据源等操作触发(对应于CRecordset::Open、CRecordset::Requery和CRecordset::Update等函数)。
2)视图与记录集
VC的MFC类库中提供了CRecordView类,是用来快速构建数据操作界面的视图类。开发时要从MFC的CRecordView类继承出自己的视图类。
视图对象与一个记录集对象绑定在一起,通过“对话框数据交换”(DDX)机制来实现视图与记录集间的信息传递,如CRecordView:: DoDataExchange。这由CWnd::UpdateData触发。
除了视图与记录集绑定这种方式外,也可以用非绑定的方式来实现视图与记录集间的交互。即用一般的视图(如CFormView)来创建数据操作界面。这种情况也是很普遍的,如果在想在一个已有程序中添加数据库操作,但是原有程序的视图类并没有从CRecordView继承,那么用非绑定的方式就可以最小限度的修改原有程序。
构造记录集对象时要把它所连接的数据源对象作为参数传递给记录集对象的构造函数,但在绑定和非绑定这两种情况下创建记录集的方式有所不同,应当引起注意:
● 在绑定的方式下,在视图中创建了记录集,并以NULL为参数传给记录集类的构造函数。具体过程是这样的,VC自动生成了一个数据源对象,并自动根据生成记录集时定义的数据源信息(在重载的CRecordset::GetDefaultConnect函数中)来打开该数据源对象,建立到相应数据源的一个连接。
● 在非绑定的方式下,记录集要自己手动创建,所以要先创建一个数据源对象,并将其作为参数传给记录集类的构造函数。如m_pMyRecordSet=new CMyRecordSet(&m_MyDBOdbc);。
3.编程技巧及注意事项
● 编程技巧及注意事项
1) 在调用CRecordset::Update函数更新数据源之前,要调用CRecordset::Edit函数做好对数据源进行更新操作的准备,否则用CWnd::UpdateData触发的对记录集的更新以及直接修改记录集数据的操作将反映不到数据源中。
2) 在调用Move之类函数(如CRecordset::MoveFirst,CRecordset::MoveNext)之前,应当调用CRecordset::IsBOF和CRecordset::IsEOF来防止出现异常。CRecordset::IsBOF判断记录集是否为空,CRecordset::IsEOF判断是否越出最后一条记录。两者都是用来判断当前记录是否有效的。
3) 当手动添加或删除记录集中对应于数据源表格字段的成员变量时,不要忘了在记录集的构造函数中修改表征字段个数的成员变量(CRecordset::m_nFields)。同样,对于参数个数的改变也要相应修改成员变量CRecordset::m_nParams。
4) 由于不同的ODBC驱动程序所支持的数据库操作能力不同,所以,对于记录集类的一些操作,在执行之前要先判断该操作是否被支持。比如Requery之前,先调用CanRestart判断能否重新检索。
5) 可以在记录集重载的CRecordset::GetDefaultSQL()函数中指定默认的SQL语句。SQL语句可先用相应的数据库管理系统(如SQL SERVER,ACCESS等)生成,保证其正确性,再写入程序中。对于设定记录集的过滤和排序等成员变量时也可采取这种办法,由于不同DBMS对表现形式定义不同,这样做可以避免出现错误。
6) 在非绑定的方式下创建记录集时,要注意数据源对象的生存期问题。一般在视图对象中维护一个记录集的成员变量,并通过如下方式来生成记录集对象:
void CmyView::CreateRecordset()
{

m_pMyRecordset=new CMyRecordset(&m_MyDBOdbc);

}
这时,由于m_pMyRecordset的作用域是整个类,而传递的数据源参数是以引用方式传递的,所以,数据源对象m_MyDBOdbc不能定义为局部变量,否则,在CreateRecordset函数之外的其它函数中使用m_pMyRecordset时,由于m_MyDBOdbc在内存中已经销毁,所以会产生异常。一般可以将m_MyDBOdbc定义为成员变量来解决此问题。
● 特殊注意事项
由于VC6.0开发环境本身还不是很完善,所以有时候会遇到意想不到的操作结果,或是与自己的预想不一样的情况,甚至会出现错误。
1) 在生成记录集时要指定记录集的类型,如动态集(dynaset),快照(snapshot)等。由于不同的ODBC驱动程序所支持的记录集类型不同,如果打开一个不支持的记录集类型时会出现异常。如果要在建立记录集后修改其类型,可以选择MFC ClassWizard的Member Variables标签页中的Update Columns,但是在VC6.0中,这样做并不能自动刷新表征记录集类型的成员变量(CRecordset::m_nDefaultTyp)。这时必须手动在记录集的构造函数中对m_nDefaultType重新赋值才行(比如把dynaset改为snapshot)。
2) 在给记录集添加查询参数时,要注意在函数DoFieldExchange中查询参数的绑定顺序,该顺序必须与定制记录集的m_strFilter属性时的顺序一致。VC的绑定参数的方法是:在函数DoFieldExchange函数中找到第一个绑定函数(以RFX_开头),以此作为第一个参数变量赋值的字段名,然后依次顺序往下进行。
如pSet->m_strFilter=” Field1=? and Field2=?”;
pSet->ParamField1=value1;
pSet->ParamField2=value2;//(参数变量赋值顺序不会产生任何不良影响)
则在记录集的DoFieldExchange函数中应以如下顺序定义参数
RFX_Long(pDX,”Field1”,ParamField1);
RFX_Long(pDX,”Field2”,ParamField2);
只要符合上述顺序,如果在后面再加上其他绑定函数,如
RFX_Long(pDX,”Field3”,ParamField3);
也不会影响,但是此函数不能放在最前面或插在中间其他地方,否则就打乱了定义的次序,从而造成变量赋值与字段名不匹配的问题。
4.结论
从以上对数据库访问的方式、程序结构及相关的编程技巧的介绍,可以看出,数据库访问的结构和程序结构是很重要的,只有在理解了这些概念后,才能在遇到实际困难时找到正确处理的办法。同样,由于数据库访问中的一些规则限制,所以数据库编程应当掌握一些基本的编程技巧和注意事项,这样才可以提高工作效率。


pengdali 2003-02-20
  • 打赏
  • 举报
回复
below is from MSDN,you can find a lot of technical article in MSDN if you search"stored procedure and VC"
good luck

Steps To Reproduce Behavior
In the SQL Server 7.0 Query Analyzer select the test database Pubs.


Create the following stored procedure. This stored procedure returns a recordset and an out parameter count.



if exists (select * from sysobjects where id = object_id(N'[dbo].[GetJobs]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
drop proc GetJobs
go
create proc GetJobs @id as int, @count as int [out] as
begin
Select @count = Count(*) from jobs where job_id >@id
Select * from jobs where job_id >@id
end
go




Use VC App Wizard to create a new console application and modify the code as follows:



#include "stdafx.h"
#include "stdio.h"
#import "C:\PROGRA~1\COMMON~1\System\ado\msado15.dll" no_namespace rename ("EOF", "EOF2")

struct InitOle {
InitOle() { ::CoInitialize(NULL); }
~InitOle() { ::CoUninitialize(); }
} _init_InitOle_;

int main(int argc, char* argv[])
{
_variant_t varErr((long)0, VT_ERROR);
_CommandPtr comm(__uuidof(Command));
_ConnectionPtr conn(__uuidof(Connection));

_bstr_t connstr="Provider=SQLOLEDB.1;Persist Security Info=False;User ID=sa;Initial Catalog=pubs;Data Source=(local)";
conn->Open(connstr, "", "", adConnectUnspecified);
comm->ActiveConnection=conn;
comm->CommandText="GetJobs";
comm->CommandType = adCmdStoredProc ;
comm->Parameters->Refresh();
_variant_t recs;

comm->Parameters->Item[_variant_t((short)1)]->Value= _variant_t((long)5);
_RecordsetPtr rs = comm->Execute(&recs, &vtMissing,adCmdStoredProc);

_variant_t recordcount= comm->Parameters->Item[_variant_t((short)2)]->Value;

printf("recordcount = %li\n", (long)recordcount);
return 0;
}



Change the Datasource, User ID and password in the connection string above.




The recordcount variant that the above code returns is of type VT_NULL rather than the number of records that the stored procedure returns.
pengdali 2003-02-20
  • 打赏
  • 举报
回复
1.配置ODBC,建立ODBC和SQL SERVER的连接ODBCTEST
2.在VC++通过该ODBC调用SQL SERVER的STORED PROCEDURE(szTypes )
#include "stdafx.h"
#include "DatabaseServer.h"
#include <stdarg.h>

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

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

CDatabaseServer::CDatabaseServer()
{

}

CDatabaseServer::~CDatabaseServer()
{

}

bool CDatabaseServer::getConnectionString(char *szConnectionString)
{
char szServerName[MAX_COMPUTERNAME_LENGTH + 1];
DWORD dwSize=sizeof(szServerName) ;
if(!GetComputerName(szServerName,&dwSize))
return false ;


if(!szConnectionString)
return false ;

char szUserName[] = "SA";
char szPassword[] = "";
char szDatabase[] = "IPLOMA";//ADD YOU DATEBASE NAME

sprintf(szConnectionString,"DSN=ODBCTEST;uid=%s;pwd=%s;",szServerName,szDatabase,szUserName,szPassword); //建立CONNECTION STRING

return true;
}

VARIANT CDatabaseServer::getExecStoredProcedure(char *szTypes,SAFEARRAY *pSPFields)
{
_variant_t vtResultRows;
try
{
_CommandPtr pCmdPtr;
_RecordsetPtr pRecordset;
HRESULT hr ;

hr = pCmdPtr.CreateInstance(__uuidof(Command));

char szConnectionString[255];
getConnectionString(szConnectionString);
_variant_t vtConnectionString(szConnectionString);
pCmdPtr->put_ActiveConnection(vtConnectionString);

pCmdPtr->CommandType = adCmdStoredProc; //CALL SQL SP
pCmdPtr->CommandText = szTypes ; //YOU SP NAME
hr = pCmdPtr->Parameters->Refresh();

long lBound,uBound ;
HRESULT hresult ;
// Getting Safe Array's Lower and Upper Bounds
hresult = SafeArrayGetLBound(pSPFields, 1, &lBound);
hresult = SafeArrayGetUBound(pSPFields, 1, &uBound);

variant_t vtParamVal;
_variant_t Index;
Index.vt = VT_I2;
Index.iVal = 1 ;
for (long iElements=lBound;iElements<=uBound;iElements++)
{
hresult = SafeArrayGetElement(pSPFields, &iElements, &vtParamVal);
pCmdPtr->GetParameters()->GetItem(Index)->PutValue(vtParamVal) ;
Index.iVal++ ;
}

//Execute current Stored Procedure
_variant_t vEffected ;
pRecordset = pCmdPtr->Execute(&vEffected,NULL,NULL);
if (pRecordset->BOF || pRecordset->EndOfFile)
throw ;
// Get result set in the form of array
vtResultRows = pRecordset->GetRows(-1);
return vtResultRows.Detach() ;
}
catch(_com_error &e)
{
ATLTRACE((LPCSTR)e.Description());
}
vtResultRows.vt = VT_EMPTY ;
return vtResultRows.Detach();
}

long CDatabaseServer::setExecStoredProcedure(char *szTypes,SAFEARRAY *pSPFields)
{
_variant_t vtResultRows;
try
{
_CommandPtr pCmdPtr;
_RecordsetPtr pRecordset;
HRESULT hr ;

hr = pCmdPtr.CreateInstance(__uuidof(Command));

char szConnectionString[255];
getConnectionString(szConnectionString);
_variant_t vtConnectionString(szConnectionString);
pCmdPtr->put_ActiveConnection(vtConnectionString);

pCmdPtr->CommandType = adCmdStoredProc;
pCmdPtr->CommandText = szTypes ;
hr = pCmdPtr->Parameters->Refresh();

long lBound,uBound;
HRESULT hresult;
// Getting Safe Array's Lower and Upper Bounds
hresult = SafeArrayGetLBound(pSPFields, 1, &lBound);
hresult = SafeArrayGetUBound(pSPFields, 1, &uBound);

variant_t vtParamVal;
_variant_t Index;
Index.vt = VT_I2;
Index.iVal = 1 ;
for (long iElements=lBound;iElements<=uBound;iElements++)
{
hresult = SafeArrayGetElement(pSPFields, &iElements, &vtParamVal);
pCmdPtr->GetParameters()->GetItem(Index)->PutValue(vtParamVal) ;
Index.iVal++ ;
}

_variant_t vEffected ;
pCmdPtr->Execute(&vEffected,NULL,NULL);

// We Are Expecting That Stored Procedures Return ID for Entity to which
// NSERT/UPDATE/DELETE operation is being performed
return (long)pCmdPtr->Parameters->Item["RETURN_VALUE"]->Value ;
}
catch(_com_error &e)
{
ATLTRACE((LPCSTR)e.Description());
}
return 0;
}
pengdali 2003-02-20
  • 打赏
  • 举报
回复
是bcb还是vc?

22,294

社区成员

发帖
与我相关
我的任务
社区描述
MS-SQL Server 疑难问题
社区管理员
  • 疑难问题社区
  • 尘觉
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧