热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

在C语言使用ODBC访问Excel,用SQLDriverConnect方法连接数据源连接字符需要哪些参数?

在C语言使用ODBC访问Excel,用SQLDriverConnect方法连接数据源连接字符需要哪些参数?MICROSOFTEXCELDRIVER(*.XLS。然后,可根据下面步骤

在C语言使用ODBC访问Excel,用SQLDriverConnect方法连接数据源连接字符需要哪些参数?

"MICROSOFT EXCEL DRIVER (*.XLS)"。然后,可根据下面步骤进行: 1. 在StdAfx.h文件中加入: #include #include 2. 通过ODBC直接创建Excel文件并在表中插入数据(暂定文件名:Demo.xls) //创建并写入Excel文件void CRWExcel::WriteToExcel(){ CDatabase database; CString sDriver = "MICROSOFT EXCEL DRIVER (*.XLS)"; // Excel安装驱动 CString sExcelFile = "c:\\demo.xls"; // 要建立的Excel文件 CString sSql; TRY { // 创建进行存取的字符串 sSql.Format("DRIVER={%s};DSN='''';FIRSTROWHASNAMES=1;READOnLY=FALSE;CREATE_DB=\"%s\";DBQ=%s", sDriver, sExcelFile, sExcelFile); // 创建数据库 (既Excel表格文件) if( database.OpenEx(sSql,CDatabase::noOdbcDialog) ) { // 创建表结构(姓名、年龄) sSql = "CREATE TABLE demo (Name TEXT,Age NUMBER)"; database.ExecuteSQL(sSql); // 插入数值 sSql = "INSERT INTO demo (Name,Age) VALUES (''徐景周'',26)"; database.ExecuteSQL(sSql); sSql = "INSERT INTO demo (Name,Age) VALUES (''徐志慧'',22)"; database.ExecuteSQL(sSql); sSql = "INSERT INTO demo (Name,Age) VALUES (''郭徽'',27)"; database.ExecuteSQL(sSql); } // 关闭数据库 database.Close(); } CATCH_ALL(e) { TRACE1("Excel驱动没有安装: %s",sDriver); } END_CATCH_ALL;} 3. 通过ODBC直接读取Excel文件(暂定文件名:Demo.xls) // 读取Excel文件void CRWExcel::ReadFromExcel() { CDatabase database; CString sSql; CString sItem1, sItem2; CString sDriver; CString sDsn; CString sFile = "Demo.xls"; // 将被读取的Excel文件名 // 检索是否安装有Excel驱动 "Microsoft Excel Driver (*.xls)" sDriver = GetExcelDriver(); if (sDriver.IsEmpty()) { // 没有发现Excel驱动 AfxMessageBox("没有安装Excel驱动!"); return; } // 创建进行存取的字符串 sDsn.Format("ODBC;DRIVER={%s};DSN='''';DBQ=%s", sDriver, sFile); TRY { // 打开数据库(既Excel文件) database.Open(NULL, false, false, sDsn); CRecordset recset(&database); // 设置读取的查询语句. sSql = "SELECT Name, Age " "FROM demo " "ORDER BY Name "; // 执行查询语句 recset.Open(CRecordset::forwardOnly, sSql, CRecordset::readOnly); // 获取查询结果 while (!recset.IsEOF()) { //读取Excel内部数值 recset.GetFieldValue("Name ", sItem1); recset.GetFieldValue("Age", sItem2); // 移到下一行 recset.MoveNext(); } // 关闭数据库 database.Close(); } CATCH(CDBException, e) { // 数据库操作产生异常时... AfxMessageBox("数据库错误: " + e->m_strError); } END_CATCH;} 4. 获取ODBC中Excel驱动的函数 CString CRWExcel::GetExcelDriver(){ char szBuf[2001]; WORD cbBufMax = 2000; WORD cbBufOut; char *pszBuf = szBuf; CString sDriver; // 获取已安装驱动的名称(涵数在odbcinst.h里) if (!SQLGetInstalledDrivers(szBuf, cbBufMax, &cbBufOut)) return ""; // 检索已安装的驱动是否有Excel... do { if (strstr(pszBuf, "Excel") != 0) { //发现 ! sDriver = CString(pszBuf); break; } pszBuf = strchr(pszBuf, ''\0'') + 1; } while (pszBuf[1] != ''\0''); return sDriver;}注意添加头文件! 还有就是数据源一定的配一下。

因为无论是access 还是sql等其他数据库,它们在安装过程中就给服务器机器安装和配置了数据源。

怎样用C语言编程实现循环把数据读入到一个excel文件指定列中或者一个excel文件中的数据读入到

最佳答案可以先用C语言格式化输出为EXCEL可以导入的文本文件,再使用EXCEL手工导入。具体导入方法可参阅《往Excel中导入TXT文本数据的三种方法》: http://tech.sina.com.cn/s/2006-05-12/1042934532.shtml 这种方法最简单, 但自动化程度低, 不能集成到你的C程序中去. 如果用C/C++创建EXCEL, 可以使用ADO或者ODBC. 如果用C++/ODBC, 可参阅《直接通过ODBC读写Excel表格文件》: http://www.vckbase.com/document/viewdoc/?id=421 还有《针对Excel表格文件操作的编程实现》: http://www.vckbase.com/document/viewdoc/?id=693 如果你的程序是用C++写的, 推荐使用以上方法. 如果用C/ODBC, 稍微麻烦一点。

我以前写过一个,好像是根据一个C++的类改写成C的, 时间太长, 记不得出处了. 现在给你做参考: 三个接口函数: OpenExcel(): 创建或打开Excel文件的一个工作表 AppendExcel(): 向工作表中加入数据记录 CloseExcel(): 结束处理 main()中示例的是建立test.xls文件, 其中两个工作表. 我这里源程序用VC6.0编译, 得到的结果在Excel 2003中可以使用. #include #include #include #ifdef _MSC_VER #pragma comment(lib,"odbc32.lib") #define SQLLEN SQLINTEGER #endif enum errtype { ERRORFREE, ERRACTION, XLSBUSY, TXTBUSY, TXTOPENERROR, SQLHANDLEENVERROR, SQLSETENVERROR, SQLHANDLEDBCERROR, SQLCONNECTERROR, SQLALLOCSTMTERROR, SQLCREATEERROR, SQLSELECTERROR, SQLBINDERROR } ; SQLHENV henv; SQLHDBC hdbc; SQLHSTMT hstmt; // ------------------------------------------------------------------------------------------------------------ static void dbError( LPSTR lp, SQLSMALLINT handleType, SQLHANDLE handle) { BYTE buf[250], sqlstate[15]; SQLGetDiagRec( handleType,handle, 1, sqlstate, NULL,buf, sizeof(buf),NULL); fprintf(stderr, "%s: %s SQLSTATE=%s\n",lp, buf, sqlstate); } // ------------------------------------------------------------------------------------------------------------ static void dbCleanup() { if (hstmt != SQL_NULL_HANDLE) { SQLFreeStmt(hstmt, SQL_UNBIND); SQLFreeHandle(SQL_HANDLE_STMT,hstmt); } if (hdbc != SQL_NULL_HANDLE) { SQLDisconnect(hdbc); SQLFreeHandle(SQL_HANDLE_DBC,hdbc); } if (henv != SQL_NULL_HANDLE) SQLFreeHandle(SQL_HANDLE_ENV,henv); } // ------------------------------------------------------------------------------------------------------------ static void dbErrorCleanup( LPSTR lp,SQLSMALLINT handleType, SQLHENV henv,SQLHDBC hdbc,SQLHSTMT hstmt) { SQLHANDLE handle; switch (handleType) { case SQL_HANDLE_STMT: handle = hstmt; break; case SQL_HANDLE_DBC: handle = hdbc; break; default: handle = henv; } if (handle != SQL_NULL_HANDLE) dbError( lp, handleType, handle ); dbCleanup(henv, hdbc, hstmt ); } //--------------------------------------------------------- static BOOL isFileOpen(const BYTE *fileName) { HANDLE hFile; // 以非共享方式打开文件. 检查EXCEL文件当前是否在使用中........... hFile = CreateFile(fileName,GENERIC_READ,0,NULL,OPEN_EXISTING,0,NULL); if (hFile == INVALID_HANDLE_VALUE) { if (GetLastError() == ERROR_SHARING_VIOLATION) return TRUE; // 使用中 else return FALSE; // 未使用中,或者无此文件(现在可以创建) } else { CloseHandle(hFile); return FALSE; } } int OpenExcel(BYTE *szExcelName, BYTE *szSheetName, BYTE *szFieldName[], BYTE *szFieldType[], int nColCount) { SQLRETURN retcode; BYTE szSql[512], *pszSql=szSql; BYTE szdatabase[256]; int rc, i; henv = hdbc = hstmt = SQL_NULL_HANDLE; if ( isFileOpen(szExcelName) ) return XLSBUSY; // 准备环境 ------------------- retcode = SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &henv); if (retcode != SQL_SUCCESS) { dbErrorCleanup( "SQLAllocHandle(ENV)",SQL_HANDLE_ENV,henv,hdbc,hstmt); return SQLHANDLEENVERROR; } retcode = SQLSetEnvAttr(henv,SQL_ATTR_ODBC_VERSION, (SQLPOINTER) SQL_OV_ODBC3,0); if (retcode != SQL_SUCCESS) { dbErrorCleanup( "SQLSetEnvAttr()",SQL_HANDLE_ENV,henv,hdbc,hstmt); return SQLSETENVERROR; } retcode = SQLAllocHandle(SQL_HANDLE_DBC, henv, &hdbc); if (retcode != SQL_SUCCESS) { dbErrorCleanup( "SQLAllocHandle(DBC)",SQL_HANDLE_ENV,henv,hdbc,hstmt); return SQLHANDLEDBCERROR; } // 与数据库建立连接 ------------------ sprintf(szdatabase,"DRIVER=Microsoft Excel Driver (*.xls);CREATE_DB=%s;DBQ=%s;READOnLY=FALSE;EXCLUSIVE=Yes;", szExcelName, szExcelName); //fprintf(stderr, "DATABASE: %s\n", szdatabase); retcode = SQLDriverConnect(hdbc, NULL, (SQLCHAR *)szdatabase, (short) (strlen(szdatabase)+1), NULL, 0, NULL, SQL_DRIVER_NOPROMPT); if (retcode != SQL_SUCCESS && retcode != SQL_SUCCESS_WITH_INFO) { dbErrorCleanup( "SQLDriverConnect()",SQL_HANDLE_DBC,henv,hdbc,hstmt); return SQLCONNECTERROR; } retcode = SQLAllocHandle(SQL_HANDLE_STMT,hdbc, &hstmt); if (retcode != SQL_SUCCESS) { dbErrorCleanup( "SQLAllocHandle(STMT)",SQL_HANDLE_DBC,henv,hdbc,hstmt); return SQLALLOCSTMTERROR; } // 构造执行 CREATE TABLE 语句 ---------------------- pszSql = szSql + sprintf(szSql, "CREATE TABLE %s (", szSheetName); for (i=0; i 去掉, printf/fprintf 改为用 MessageBox 提供必要的输出信息或干脆删掉。

如何在VB中注册sql数据源?需要详细步骤或者成功实例

连接数据源本教程中,我们将学习使用ODBC APIs的细节.因为我们的程序并不与ODBC驱动程序直接通信,而是通过ODBC管理器来定义一系列APIs供你的程序调用以完成工作,所以我们需要包含odbc32.inc和odbc32.lib文件,当然还有windows.inc。连接数据源需要以下几步:分配一个环境句柄(environment handle). 在进行每个ODBC任务(session)时仅需这样做一次.一旦获得了句柄,我们就可修改环境属性来适合我们的需要。

你可以把这想象为在DB工作中创建一个workspace. 确认将使用的ODBC的版本. 你可在ODBC 2.x版和3.x版间选择.他们在很多方面存在不同,因此本步骤是必须的以使得ODBC管理器它将用何种语法与用户程序通讯,及如何解释用户程序的命令. 分配一个连接句柄.这个步骤可看作创建一个空连接.我们还没有指定使用那一个驱动程序,连接那一个数据库.这些信息将在稍后来写入. 建立一个连接.可通过调用ODBC函数来建立连接. 当连接完成时,必须通过以下步骤来关闭和销毁它:断开与数据源的连接. 释放连接句柄. 释放环境句柄 (如果不再需要在这个环境中作更多连接) 分配一个句柄在ODBC 3.x版本以前,我们需要调用很多独立的函数来分配环境、连接和语句句柄(SQLAllocEnv, SQLAllocConnect, SQLAllocStmt).而在ODBC 3.x中, 这些函数被SQLAllocHandle所代替,语法如下:SQLRETURN SQLAllocHandle( SQLSMALLINT HandleType, SQLHANDLE InputHandle, SQLHANDLE * OutputHandlePtr ); 看上去挺麻烦,简化一下看看: SQLAllocHandle proto HandleType:DWORD, InputHandle:DWORD, OutputHandlePtr:DWORDSQLRETURN 被定义为SQLSMALLINT类型.而 SQLSMALLINT被定义为短整型,例如一个字(16 bits). 所以该函数的返回值在ax中,而不是 eax. 这是很重要的.但是Win32下函数的参数是通过32位堆栈来传送的.即使这个参数只是一个字长(16位),它也应被扩展为32位.这就是为什么HandleType被说明为双字(dword)而不是字(word).看一下导入库 odbc32.lib,SQLAllocHandle的入口是_SQLAllocHandle@12. 就是说这个函数的参数的组合长度为12字节(3 dwords).然而,这不是说C函数的原型不对. SQLAllocHandle会只用HandleType的底位字并忽略高位字.因此C函数原型是功能上(functionally)正确而我们的汇编函数原型反映了实际.结束了SQL类型的讨论,我们来看一看函数的参数和返回值。

.HandleType 是一个常数,定义了希望分配的句柄类型.可能值如下: SQL_HANDLE_ENV 环境句柄(Environment handle)SQL_HANDLE_DBC连接句柄(Connection handle)SQL_HANDLE_STMT语句句柄(Statement handle)SQL_HANDLE_DESC描述符句柄(Descriptor handle)描述符是一个数据集合描述了一个SQL语句的参数或一个结果集的列数, 视应用程序或驱动程序而定。InputHandle 是指向父"文本"的句柄.就是说,如果你想分配一个连接句柄, 需要通过一个环境句柄因为连接将在那个环境的文本中建立.如果你想分配一个环境句柄,这个参数必须为SQL_HANDLE_NULL (注意SQL_HANDLE_NULL在windows.inc版本1.18及其以前版本中被不正确的定义为0L.你需要删除掉"L"否则程序不会被编译通过.这是我的错,因为我负责修订windows.inc中的 SQL/ODBC部分.) 因为环境没有父文本.对于语句和描述符句柄,我们需要将连接句柄作为这个参数。 OutputHandlePtr 如果调用成功,将指向一个双字,其中包含了被分配的句柄. SQLAllocHandle 可能的返回值如下:SQL_SUCCESS函数成功完成.SQL_SUCCESS_WITH_INFO函数成功完成,但带回非致命错误或警告. SQL_ERROR函数调用失败.SQL_INVALID_HANDLE传送给函数的句柄非法.无论函数的调用成功还是失败,我们都可通过调用SQLGetDiagRec或SQLGetDiagField函数来获得更多的信息.它们与Win32 API中的GetLastError很相似.例子:.data?hEnv dd ?.codeinvoke SQLAllocHandle, SQL_HANDLE_ENV, SQL_HANDLE_NULL, addr hEnv.if ax==SQL_SUCCESS || ax==SQL_SUCCESS_WITH_INFO选择ODBC的版本分配完环境句柄后,我们需要设置一个环境属性SQL_ATTR_ODBC_VERSION以适当的值.设置环境属性可通过调用函数SQLSetEnvAttr.你也许猜到了,还有类似的函数如 SQLSetConnectAttr和SQLSetStmtAttr. SQLSetEnvAttr原型如下:SQLSetEnvAttr proto EnvironmentHandle:DWORD,Attribute:DWORD,ValuePtr:DWORD, StringLength:DWORDEnvironmentHandle. 与字面意思一样, 它包含了要设置属性的环境句柄. Attribute. 这是一个常数,表示用户需要设置的属性.对我们而言,是SQL_ATTR_ODBC_VERSION.可以从MSDN中查看全部列表. ValuePtr. 这个参数的意义由希望设置的属性值决定.如果属性值是32位的, 这个参数将被认为是想要设置的属性值.如果属性值是一个字符串或二进制缓冲区,它就被解释为指向字符串或缓冲区的指针.如果我们指定了要设置的属性为SQL_ATTR_ODBC_VERSION, 这个参数我们可以填入SQL_OV_ODBC3和SQL_OV_ODBC2这两个可能值,分别对应ODBC 3.x和2.x. StringLength. 由ValuePtr指向的值的长度. 如果这个值是字符串或二进制缓冲区,这个参数一定是合法的. 如果想设置的属性是一个双字,这个参数被忽略.因为 SQL_ATTR_ODBC_VERSION属性包含一个双字的值,我们可以只给它赋为NULL. 这个函数的返回值与SQLAllocHandle相同.例子:.data?hEnv dd ?.codeinvoke SQLAllocHandle, SQL_HANDLE_ENV, SQL_HANDLE_NULL, addr hEnv.if ax==SQL_SUCCESS || ax==SQL_SUCCESS_WITH_INFOinvoke SQLSetEnvAttr, hEnv, SQL_ATTR_ODBC_VERSION, SQL_OV_ODBC3, NULL.if ax==SQL_SUCCESS || ax==SQL_SUCCESS_WITH_INFO分配连接句柄这一步与分配环境句柄相似,我们可以通过调用SQLAllocHandle函数并赋以不同的参数值来完成.例子:.data?hEnv dd ?hConn dd ?.codeinvoke SQLAllocHandle, SQL_HANDLE_ENV, SQL_HANDLE_NULL, addr hEnv.if ax==SQL_SUCCESS || ax==SQL_SUCCESS_WITH_INFOinvoke SQLSetEnvAttr, hEnv, SQL_ATTR_ODBC_VERSION, SQL_OV_ODBC3, NULL.if ax==SQL_SUCCESS || ax==SQL_SUCCESS_WITH_INFOinvoke SQLAllocHandle, SQL_HANDLE_DBC, hEnv, addr hConn.if ax==SQL_SUCCESS || ax==SQL_SUCCESS_WITH_INFO建立一个连接我们现在要通过特定的ODBC驱动程序来连接数据源.通过这三个ODBC函数来达成这个目标.它们为我们提供了好几层"选择".SQLConnectCore这是最简单的函数。它只需要数据源名(DSN,Data source name)和可选的用户名和密码.它不提供任何GUI选项例如向用户显示一个对话框来提供更多信息。

如果你已经有了需要使用的数据库的DSN就可以使用这个函数.SQLDriverConnectCore这个函数提供了较SQLConnect更多的选择.我们可以连接一个没有在系统信息内定义的数据源。如没有DSN.另外,我们可以指定这个函数是否需要显示一个对话框来为用户提供更多信息.例如,如果用户遗漏了数据库的名字,它会指导ODBC驱动程序显示一个对话框,让用户来选择想连接的数据库.SQLBrowseConnectLevel 1这个函数允许在运行时(RunTime)枚举数据源.比SQLDriverConnect更加灵活。因为可以多次顺序调用SQLBrowseConnect,而每次提供给使用者更多的专用信息直到最后获得需要的连接句柄.我将先检查SQLConnect函数.要使用 SQLConnect,你应先知道什么是DSN. DSN是数据源名(Data Source Name)的缩写,是一个唯一标识某数据源的字符串。

一个DSN标识了一个包含了如何连接某一特定的数据源的信息的数据结构.这个信息包括要使用何种ODBC驱动程序及要连接哪个数据库.我们可以通过控制面板中的32位ODBC数据源来创建、修改及删除DSN. SQLConnect的语法如下:SQLConnect proto ConnectionHandle:DWORDpDSN:DWORD,DSNLength:DWORD,pUserName:DWORD,NameLength:DWORD,pPassword:DWORD,PasswordLength:DWORDConnectionHandle. 要使用的连接句柄. pDSN. 指向DSN的指针. DSNLength. DSN的长度 pUserName. 指向用户名的指针 NameLength. 用户名的长度 pPassword. 指向该用户名所使用密码的指针 PasswordLength. 密码的长度 在最小情况下, SQLConnect 需要连接句柄,DSN和DSN的长度。如果数据源不需要的话,用户名和密码就不是必须的.函数的返回值与SQLAllocHandle的返回值相同.假设我们的系统中有一个叫做"Sales" 的DSN并且我们想连接这个数据源.我们可以这样做:.dataDSN db "Sales",0.code......invoke SQLConnect, hConn, addr DSN, sizeof DSN,0,0,0,0SQLConnect 的缺点是:在连接一个数据源之前,我们必须创建它的DSN. SQLDriverConnect 提供了更大的灵活性.它的语法如下:SQLDriverConnect proto ConnectionHandle:DWORD,hWnd:DWORD,pInConnectString:DWORD,InStringLength:DWORD,pOutConnectString:DWORD,OutBufferSize:DWORD,pOutConnectStringLength:DWORD, DriverCompletion:DWORDConnectionHandle连接句柄 hWnd 应用程序窗口句柄.如果这个参数被置为NULL,驱动程序将不会为用户显示一个对话框来显示更多信息(如果有的话). pInConnectString 指向连接字符串的指针. 这是一个ASCIIZ字符串,格式由要连接的具体ODBC驱动程序描述.它描述了驱动程序名、数据源及其他附加属性.连接字符串的具体描述请参见MSDN,这里不再细述. InStringLength 连接字符串的长度. pOutConnectString 指向将要被填入完整连接字符串的缓冲区的指针.这个缓冲区将至少有1,024字节长.这听上去使人困惑。事实上,我们提供的连接字符串会不完整,这时,ODBC驱动程序会提示用户更多信息.接下来ODBC驱动程序会根据所有可能的信息创建一个完整的连接字符串并将其放入缓冲区。

即使我们提供的连接字符串已经可以工作了,这个缓冲区也会填入更多的属性值.这个参数的目的是我们可以保存完整连接字符串来为接下来的连接做准备。 OutBufferSize 由pOutConnectString指向的缓冲区的长度. pOutConnectStringLength 指向一个双字的指针,用来接收由ODBC驱动程序返回的完整连接字符串的长度。 DriverCompletion 一个标志用来指示ODBC管理器/驱动程序是否将提示用户更多信息.但是,这个标志取决于是否在调用本函数时传送了hWnd 参数一个窗口句柄。

如果没有,即使该标志被设置,ODBC管理器/驱动程序也不会提示用户.可能值如下:SQL_DRIVER_PROMPTODBC驱动程序提示用户输入信息。驱动程序将利用这些信息来创建连接字符串.SQL_DRIVER_COMPLETESQL_DRIVER_COMPLETE_REQUIRED 仅当用户提供的连接字符串不完全时, ODBC驱动程序才会提示用户.SQL_DRIVER_NOPROMPTODBC驱动程序将不会提示用户.例子:.datastrConnect db "DBQ=c:\data\test.mdb;DRIVER={Microsoft Access Driver (*.mdb)};",0 .data?buffer db 1024 dup(?)OutStringLength dd ?.code.....invoke SQLDriverConnect, hConn, hWnd, addr strConnect, sizeof strConnect, addr buffer, sizeof buffer, addr OutBufferLength, SQL_DRIVER_COMPLETE断开与数据源的连接在连接顺利完成后,我们就可以对数据源进行查询及其他操作.这些将在下一节讨论.现在假设我们已完成了对数据源的操作,就可以通过调用SQLDisconnect来断开与它的连接. 这个函数非常简单(就象那悲伤而冷酷的现实:毁灭总比创造容易的多).它只需要一个参数:连接句柄。

SQLSERVER中的MARS结果集是什么东东

MSDN上的解释:SQL Server 2005 在访问数据库引擎的应用程序中引入了对多个活动结果集 (MARS) 的支持。在 SQL Server 的早期版本中,数据库应用程序无法在单个连接上保持多个活动语句。

使用 SQL Server 默认结果集时,应用程序必须先处理或取消自某一批处理生成的所有结果集,然后才能执行该连接上的其他任何批处理。

SQL Server 2005 引入了新连接属性,支持应用程序在每个连接上拥有多个待定请求,特别是支持每个连接具有多个活动的默认结果集。MARS 通过以下新功能简化了应用程序设计:应用程序可以同时打开多个默认结果集,并且交错读取它们。应用程序可以在默认结果集打开的同时执行其他语句(例如 INSERT、UPDATE、DELETE 和存储过程调用)。下列指南对使用 MARS 的应用程序很有帮助:默认结果集应该用于使用单个 SQL 语句(SELECT、带 OUTPUT 的 DML、RECEIVE、READ TEXT 等)生成的短期或较小结果集。

服务器游标应该用于使用单个 SQL 语句生成的长期或较大结果集。对于过程请求(不论它们是否返回结果)以及返回多个结果的批处理,应始终读取到它们的结果的末尾。尽可能使用 API 调用(而不是 Transact-SQL 语句)更改连接属性和管理事务。

在 MARS 中,有多个批处理并发运行时禁止会话范围内的模拟。在SQL2000的时候,一个连接同时只能运行一个批处理指令。也就是说一个连接在一个时间点只能有一个请求在运行。

但是SQL2005以后,如果使用了MARS技术,一个连接可以同时开启多个结果集。而sys.sysprocesses视图不能正确显示这种行为。

如何将C语言的输出倒入Excel工作表

可以先用C语言格式化输出为EXCEL可以导入的文本文件,再使用EXCEL手工导入。具体导入方法可参阅《往Excel中导入TXT文本数据的三种方法》:http://tech.sina.com.cn/s/2006-05-12/1042934532.shtml这种方法最简单, 但自动化程度低, 不能集成到你的C程序中去.如果用C/C++创建EXCEL, 可以使用ADO或者ODBC.如果用C++/ODBC, 可参阅《直接通过ODBC读写Excel表格文件》:http://www.vckbase.com/document/viewdoc/?id=421还有《针对Excel表格文件操作的编程实现》:http://www.vckbase.com/document/viewdoc/?id=693如果你的程序是用C++写的, 推荐使用以上方法.如果用C/ODBC, 稍微麻烦一点。

我以前写过一个,好像是根据一个C++的类改写成C的, 时间太长, 记不得出处了. 现在给你做参考:三个接口函数:OpenExcel(): 创建或打开Excel文件的一个工作表AppendExcel(): 向工作表中加入数据记录CloseExcel(): 结束处理main()中示例的是建立test.xls文件, 其中两个工作表. 我这里源程序用VC6.0编译, 得到的结果在Excel 2003中可以使用.#include #include #include #ifdef _MSC_VER#pragma comment(lib,"odbc32.lib")#define SQLLEN SQLINTEGER#endifenum errtype { ERRORFREE, ERRACTION, XLSBUSY, TXTBUSY, TXTOPENERROR, SQLHANDLEENVERROR, SQLSETENVERROR, SQLHANDLEDBCERROR, SQLCONNECTERROR, SQLALLOCSTMTERROR, SQLCREATEERROR, SQLSELECTERROR, SQLBINDERROR } ;SQLHENV henv;SQLHDBC hdbc;SQLHSTMT hstmt;// ------------------------------------------------------------------------------------------------------------static void dbError( LPSTR lp, SQLSMALLINT handleType, SQLHANDLE handle) { BYTE buf[250], sqlstate[15]; SQLGetDiagRec( handleType,handle, 1, sqlstate, NULL,buf, sizeof(buf),NULL); fprintf(stderr, "%s: %s SQLSTATE=%s\n",lp, buf, sqlstate);}// ------------------------------------------------------------------------------------------------------------static void dbCleanup() { if (hstmt != SQL_NULL_HANDLE) { SQLFreeStmt(hstmt, SQL_UNBIND); SQLFreeHandle(SQL_HANDLE_STMT,hstmt); } if (hdbc != SQL_NULL_HANDLE) { SQLDisconnect(hdbc); SQLFreeHandle(SQL_HANDLE_DBC,hdbc); } if (henv != SQL_NULL_HANDLE) SQLFreeHandle(SQL_HANDLE_ENV,henv);}// ------------------------------------------------------------------------------------------------------------static void dbErrorCleanup( LPSTR lp,SQLSMALLINT handleType, SQLHENV henv,SQLHDBC hdbc,SQLHSTMT hstmt){ SQLHANDLE handle; switch (handleType) { case SQL_HANDLE_STMT: handle = hstmt; break; case SQL_HANDLE_DBC: handle = hdbc; break; default: handle = henv; } if (handle != SQL_NULL_HANDLE) dbError( lp, handleType, handle ); dbCleanup(henv, hdbc, hstmt );}//---------------------------------------------------------static BOOL isFileOpen(const BYTE *fileName){ HANDLE hFile; // 以非共享方式打开文件. 检查EXCEL文件当前是否在使用中........... hFile = CreateFile(fileName,GENERIC_READ,0,NULL,OPEN_EXISTING,0,NULL); if (hFile == INVALID_HANDLE_VALUE) { if (GetLastError() == ERROR_SHARING_VIOLATION) return TRUE; // 使用中 else return FALSE; // 未使用中,或者无此文件(现在可以创建) } else { CloseHandle(hFile); return FALSE; }}int OpenExcel(BYTE *szExcelName, BYTE *szSheetName, BYTE *szFieldName[], BYTE *szFieldType[], int nColCount){ SQLRETURN retcode; BYTE szSql[512], *pszSql=szSql; BYTE szdatabase[256]; int rc, i; henv = hdbc = hstmt = SQL_NULL_HANDLE; if ( isFileOpen(szExcelName) ) return XLSBUSY; // 准备环境 ------------------- retcode = SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &henv); if (retcode != SQL_SUCCESS) { dbErrorCleanup( "SQLAllocHandle(ENV)",SQL_HANDLE_ENV,henv,hdbc,hstmt); return SQLHANDLEENVERROR; } retcode = SQLSetEnvAttr(henv,SQL_ATTR_ODBC_VERSION, (SQLPOINTER) SQL_OV_ODBC3,0); if (retcode != SQL_SUCCESS) { dbErrorCleanup( "SQLSetEnvAttr()",SQL_HANDLE_ENV,henv,hdbc,hstmt); return SQLSETENVERROR; } retcode = SQLAllocHandle(SQL_HANDLE_DBC, henv, &hdbc); if (retcode != SQL_SUCCESS) { dbErrorCleanup( "SQLAllocHandle(DBC)",SQL_HANDLE_ENV,henv,hdbc,hstmt); return SQLHANDLEDBCERROR; } // 与数据库建立连接 ------------------ sprintf(szdatabase,"DRIVER=Microsoft Excel Driver (*.xls);CREATE_DB=%s;DBQ=%s;READOnLY=FALSE;EXCLUSIVE=Yes;", szExcelName, szExcelName); //fprintf(stderr, "DATABASE: %s\n", szdatabase); retcode = SQLDriverConnect(hdbc, NULL, (SQLCHAR *)szdatabase, (short) (strlen(szdatabase)+1), NULL, 0, NULL, SQL_DRIVER_NOPROMPT); if (retcode != SQL_SUCCESS && retcode != SQL_SUCCESS_WITH_INFO) { dbErrorCleanup( "SQLDriverConnect()",SQL_HANDLE_DBC,henv,hdbc,hstmt); return SQLCONNECTERROR; } retcode = SQLAllocHandle(SQL_HANDLE_STMT,hdbc, &hstmt); if (retcode != SQL_SUCCESS) { dbErrorCleanup( "SQLAllocHandle(STMT)",SQL_HANDLE_DBC,henv,hdbc,hstmt); return SQLALLOCSTMTERROR; } // 构造执行 CREATE TABLE 语句 ---------------------- pszSql = szSql + sprintf(szSql, "CREATE TABLE %s (", szSheetName); for (i=0; i 去掉, printf/fprintf 改为用 MessageBox 提供必要的输出信息或干脆删掉。

请高手进来帮忙,关于SQL和网络通信链接失败的问题,追加50分。

VB访问SQL Server数据库技术全揭密 摘 要: 本文讨论了Visual Basic应用程序访问SQL Server数据库的几种常用的方法,分别说明了每种方法的内部机理并给出了每种方法的一个简单的实例,最后比较了每种方法性能和优缺点。 一、引言 SQL Server是微软推出的中小型网络数据库系统,是目前最常用的数据库系统之一。

随着SQL Server网络数据库应用程序日益增多,这种Web数据库应用系统的正常运行一般依赖于已存在的用户数据库。

创建维护数据库的工作可用SQL Server提供的SQL Enterprise Manager工具来进行,如能提供一种定制的数据库管理工具,通过管理应用程序来管理数据库及其设备,对用户来说无疑是最理想的。 Visual Basic作为一种面向对象的可视化编程工具,具有简单易学,灵活方便和易于扩充的特点。而且Microsoft为其提供了与SQL Server通信的API函数集及工具集,因此它越来越多地用作大型公司数据和客户机—服务器应用程序的前端,与后端的Microsoft SQL Server相结合,VB能够提供一个高性能的客户机—服务器方案。 二、VB访问SQL Server数据的常用方法 使用Visual Basic作为前端开发语言,与SQL Server接口有几种常用的方法,即: ①数据访问对象/Jet ②为ODBC API编程 ③使用SQL Server的Visual Basic库(VBSQL)为DB库的API编程 ④RDO 远程数据对象(RemoteData Objects) ⑤ADO 数据对象(Active Data Objects) 1、数据访问对象/Jet VB支持Data Access Objects(DAOs)的子集。

DAO的方法虽然不是性能最好的管理客户机—服务器之间的对话方式,但它的确有许多优点。DAO/Jet是为了实现从VB访问Access数据库而开发的程序接口对象。使用DAOs访问SQL Server的过程如下:应用程序准备好语句并送至Jet,Jet引擎(MASJT200.DLL)优化查询,载入驱动程序管理器并与之通讯,驱动程序管理器(ODBC.DLL)通过调用驱动器(SQLSRVR.DLL)的函数,实现连接到数据源,翻译并向SQL Server提交SQL语句且返回结果。

下面是一个用DAOs访问SQL Server的VB实例。 注释:Form Declarations Dim mydb As Database Dim mydynaset As Dynaset オ Private Sub Form_Load() Set mydb = OpenDatabase("", False, False, "ODBC; DSN=Myserver; WSID=LCL; DATABASE = sales") Set mydynaset = mydb CreateDynaset("Select*from Customers") オ End Sub ァ 上述例子是以非独占、非只读方式打开sales数据库,并检索Customers表中的所有字段。OpenDatabase函数的最后一个参数是ODBC连接字符串参数,它指明了Microsoft Access连接到SQL Server所需要知道的一些内容。

其中“DSN”为数据源名,“WSID”为工作站名,“DATABASE”为所要访问的数据库名。 2、利用ODBC API编程 ODBC(Open Database Connectivity)的思想是访问异种数据库的一种可移植的方式。与数据资源对话的公用函数组装在一个称为驱动程序管理器(ODBC.DLL)的动态连接中。

应用程序调用驱动程序管理器中的函数,而驱动程序管理器反过来通过驱动器(SQLSRVR.DLL)把它们送到服务器中。 下面的代码使用上面一些函数先登录到一个服务器数据库,并为随后的工作设置了语句句柄。 Global giHEnv As Long Global giHDB As Long Global giHStmt As Long Dim myResult As integer Dim myConnection As Srting Dim myBuff As String*256 Dim myBufflen As Integer If SQLAllocEnv(giHEnv)<>SQL_SUCCESS Then MsgBox"Allocation couldn注释:t happen!" End If If SQLAllocConnect(giHEnv,giHDB)<>SQL_SUCCESS Then MsgBox "SQL Server couldn注释:t connect!" End If myCOnnection="DSN=myServer;UID=LCL;PWD=;APP=ODBCTest;WSID=LCL;DATABASE=sales" myResult=SQLDriverConnect(giHDB,Test,form1.hWnd,myConnection.len(myConnection),myBuff,256,myBufflen,SQL_DRIVER_COMPLETE_REQU IE D) myResult=SQLAllocStmt(giHDS,giHStmt) myResult=SQLFreeStmt(giHStmt,SQL_COLSE) rsSQL="Select * from Customers Where City = "Hunan"" myResult = SQLExecDirect(giHStmt,rsSQL,Len(rsSQL)) 3、使用VBSQL对DB库API编程 DB库是SQL Server的本地API,SQL Server的Visual Basic库(VBSQL)为Visual Basic程序员提供API。从一定意义上说,VBSQL是连接Visual Basic程序到SQL Server的性能最好最直接的方式。

VBSQL包含以下三个文件: VBSQL.VBX: 包含库函数,具有访问重要的消息和处理错误的能力 VBSQL.BI:包括所有的常量和变量说明 VBSQL.HLP:Windows帮助文件,使用VBSQL的指南 使用VBSQL时,必须将VBSQL.BI加入到Visual Basic工程文件中,并确保VB程序运行时有VBSQL.VBX文件。 一般的DB库API编程的过程是这样的:先通过调用SqlInit对DB库进行初始化,再调用SqlConnection打开一个连接,然后就可做一些工作。下面的代码是一个初始化DB库并登录到服务器的通用例程。 Private Sub InitializeApplication() DBLIB_VERSION=SqlInit() If DBLIB_VERSION=""Then MsgBox"Could not initialize DBLIB!Exit application.", MB_ICONEXCLAMATION End If End Sub Private Function LoginToServer() As integer loginToServer=SUCCEED Status%=SqlSetloginTime%(loginTimeOut) If giSqlConn<>0 Then SqlClose(giSqlConn) 注释:关闭已打开的连接 giSqlCOnn=SqlOpenConnection(gsServerName, gsLoginID, gsPassword, ProgramName, ProgramName) If giSqlConn<>0 Then liresuit=SqlUse(giSqlConn,"Sales") Else LogintoServer=FAIL End If End Function 4、RDO 远程数据对象(RemoteData Objects) 要讨论RDO,就必然要谈到DAO。

RDO是从DAO派生出来的,但两者很大的不同在于其数据库模式。DAO是针对[记录(Records)]和[字段( Fields)],而RDO是作为[行(Rows)]和[列(Columns)]来处理。也就是说DAO 是ISAM模式,RDO是关系模式。此外DAO是访问Access的Jet引擎(Jet是ISAM)的接口,而RDO则是访问ODBC的接口。

可见,RDO是综合了DAO/Jet、VBSQL/DBLib以及ODBC的优点的对象(Object)。需要强调的是,RDO是包裹着ODBC API的一层薄薄的外壳, 被设计成在后台(服务器端)有数据库存在的前提下运行,同时也是针对SQL Server和Oracle而特别设计的。 RDO的优势在于它完全被集成在VB之中。

此外,直接访问SQL Server存储过程、完全支持T-SQL、T-SQL调试集成在开发环境中、Visual Database Tools的集成化等,也是RDO的长处。 在RDO的对象和集合中,有很多对数据库的状态和设定进行操作的属性(Property),以及对数据库进行操作的方法(Method)。利用这些,从RDO2.0起就可以开发事件驱动的数据库应用程序。

RDO对象与VB中其他对象的概念相同。与VB用的ActiveX控件(以往称为Custom Control或OCX、VBX)相似的是,RDO也带有属性和方法;但同Spread、InputMan等普遍应用的ActiveX控件不同的是,RDO没有自己的用户界面,因而可以和VB标准的Timer控件归为同一类。当然也可以将RDO看作调用ODBC API函数,进而对后台数据库操作加以控制的对象。在RDO的属性和方法中,包含了对单个的ODBC API函数以及一连串API函数的调用。

①rdoEngine对象 最初调用RDO对象以及RDC(远程数据控件)时,自动生成rdoEngine对象的附带事件(incident)。rdoEngine用于对RDO全局属性的参数、选项进行设置,是在RDO的阶层结构内处于最上层的对象,包含了所有的其他对象。 rdoEngine对象与DAO/Jet不同,虽然被多个应用程序共享,但体现rdoEngine对象的设定值的属性却并不共用,而是在各自的应用程序的程序界面中对其分别加以设定。

这些设定值对其他使用RDO以及RDC的应用程序没有任何影响。rdoEngine不是集合的要素,而是重新定义的对象,rdoEngine对象不能被追加作成对象属性的初值。 ②rdoEnvironment对象 RDO对象在自动创建rdoEngine对象时,将rdoEnviroment对象的初始值生成并保存为rdoEnviroments(0)。一般情况下,应用程序中不必追加rdoEnvironment对象,大多只需对已有的rdoEnviroments(0)进行操作就可以了。

只有在支持一个以上事务(Transaction),需要将用户名和口令信息分别处理的情况下,利用rdoCreateEnvironment方法将特定的用户名和口令值做成新的rdoEnvironment对象。在这个方法中可以指定固有名、用户名和口令,如果所指定的值与rdoEnvironments集合的已经存在的成员名称相同,会产生错误。新建的rdoEnvironment对象自动追加在rdoEnvironments集合的最后。

调rdoCreateEnvironment方法时,其name参数可以是长度为0的文字列,这时新的rdoEnvironment对象将不会被追加在rdoEnvironments集合之中。 ③rdoConnection对象 rdoConnection对象用于同SQL Server的连接管理。 下面是与SQL Server连接的例子。 用OpenConnection方法的一个实例。


推荐阅读
author-avatar
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有