ADO对SQL Server 2008数据库的基础操作

最近在学习ADO与数据库的相关知识,现在我将自己学到的东西整理写出来,也算是对学习的一种复习。

这篇文章主要说明如何遍历某台机器上所有的数据库服务,遍历某个服务中所有的数据库,遍历数据库中的所有表以及表中所有字段字段,最后再说明如何通过ADO操作数据库中的表。

一、遍历所有数据库服务:

遍历数据库服务我们通过函数NetServerEnum来实现,该函数可以 遍历局域网中所有的服务可以通过指定服务类型来有筛选的进行枚举,以达到遍历所有数据库服务的目的,该函数的原型如下:

NET_API_STATUS NetServerEnum(
  _In_opt_    LPCWSTR servername,
  _In_        DWORD   level,
  _Out_       LPBYTE  *bufptr,
  _In_        DWORD   prefmaxlen,
  _Out_       LPDWORD entriesread,
  _Out_       LPDWORD totalentries,
  _In_        DWORD   servertype,
  _In_opt_    LPCWSTR domain,
  _Inout_opt_ LPDWORD resume_handle
);

各个参数的说明如下:

servername:这个参数是系统保留的必须为NULL

level:参数用于指明返回参数的结构体的版本,主要有100和101两个值,分别对应SERVER_INFO_100和SERVER_INFO_100;

bufptr:是一个返回参数,系统在这个指针所指向的区域中填充一个SERVER_INFO_100或SERVER_INFO_100的结构体,具体使用哪一种由上一个参数指定;

prefmaxlen:返回值的最大长度,以字节为单位,一般我们设置为MAX_PREFREED_LENGHT,这个参数表明,具体需要多大的缓冲由函数指定

entriesread:由函数返回,表示当前获取的枚举的数量

totalentries:由函数返回,表示当前机器上所有的服务的总数

servertype:获取的服务的类型;(具体类型请参阅MSDN,我们这里主要用的是SV_TYPE_SQLSERVER获取数据库服务)

domain:一个常量字符串,用于指定要返回服务器列表域的名称,如果这个值为NULL则域名是隐含的

resume_handle:保留参数,该参数必须为NULL;

以下是实现的代码,大部分是从MSDN上Copy下来的,只是修改了小部分代码:

#include "stdafx.h"
#include <iostream>
#include <windows.h>
#include <lm.h>
using namespace std;
#pragma comment(lib, "netapi32.lib")
int _tmain(int argc, _TCHAR* argv[])
{
	LPSERVER_INFO_101 pBuf = NULL;
	LPSERVER_INFO_101 pTmpBuf;

	DWORD dwLevel = 101;
	DWORD dwPrefMaxLen = MAX_PREFERRED_LENGTH;
	DWORD dwEntriesRead = 0;
	DWORD dwTotalEntries = 0;
	DWORD dwTotalCount = 0;
	DWORD dwServerType = SV_TYPE_SQLSERVER;        // SQL SERVER
	DWORD dwResumeHandle = 0;
	NET_API_STATUS nStatus;
	LPWSTR pszServerName = NULL;
	LPWSTR pszDomainName = NULL;
	DWORD i;

	nStatus = NetServerEnum(pszServerName, dwLevel, (LPBYTE *)&pBuf, dwPrefMaxLen, &dwEntriesRead, &dwTotalEntries, dwServerType,
		pszDomainName, &dwResumeHandle);

	if ((nStatus == NERR_Success) || (nStatus == ERROR_MORE_DATA))
	{
		if ((pTmpBuf = pBuf) != NULL)
		{			
			for (i = 0; i < dwEntriesRead; i++) //成功则依次输出结果
			{
				assert(pTmpBuf != NULL);
				printf("\tPlatform: %d\n", pTmpBuf->sv101_platform_id);
				wprintf(L"\tName:     %s\n", pTmpBuf->sv101_name);
				printf("\tVersion:  %d.%d\n",pTmpBuf->sv101_version_major, pTmpBuf->sv101_version_minor);
				printf("\tType:     sql server");
				printf("\n");					
				wprintf(L"\tComment:  %s\n\n", pTmpBuf->sv101_comment);

				pTmpBuf++;
				dwTotalCount++;
			}
		}
		else 
		{
			printf("No servers were found\n");
			printf("The buffer (bufptr) returned was NULL\n");
			printf("  entriesread: %d\n", dwEntriesRead);
			printf("  totalentries: %d\n", dwEntriesRead);
		}

	}
	else//函数执行错误
	{
		fprintf(stderr, "NetServerEnum failed with error: %d\n", nStatus);
	}
	if (pBuf != NULL)
	{
		NetApiBufferFree(pBuf);//释放内存空间
	}
}

二、遍历数据库中服务器中所有数据库:

通过上一步我们可以遍历局域网中所有数据库服务,这个时候我们更进一步来遍历数据库服务中所有的数据库,实现这个功能没有什么特殊的函数,主要是对系统表的应用,我们用的是系统表master.sys.database,该表中记录了服务中所有的数据库,通过ADO的方式来进行操作:

//初始化COM组件库
CoInitialize(NULL);
_ConnectionPtr pConnect;
HRESULT hErr;
try
{
	//创建Connection对象
	hErr = pConnect.CreateInstance("ADODB.Connection");
	if (SUCCEEDED(hErr))
	{
		pConnect->Open("Driver={SQL Server};Server=LIUHAO-PC;Uid = sa;Pw = 1234", "", "", adModeUnknown);
	}
}
catch (_com_error &e)
{
	cout << e.Description() << endl;
}

try
{
	//创建RECORD, COMMAND对象
	_RecordsetPtr pRecord;
	pRecord.CreateInstance("ADODB.Recordset");
	_CommandPtr pCommand;
	pCommand.CreateInstance("ADODB.Command");
       //遍历服务器中所有数据库
	cout << "服务器中所有数据库:" << endl;
	pRecord->Open("select * from master.sys.databases", pConnect.GetInterfacePtr(), adOpenStatic, adLockOptimistic, adCmdText);
	_variant_t vName;
	while (!pRecord->adoEOF)
	{
		vName = pRecord->GetCollect(_variant_t("name"));
		wcout << (TCHAR*)_bstr_t(vName) << endl;
		pRecord->MoveNext();
	}
	pRecord->Close();
}
catch
{
	cout << e.Description() << endl;
}

三、遍历某个数据库中所有的表:

该操作也是使用系统表的内容,代码如下:

//遍历test数据库中所有表
cout << "数据库中所有表:" << endl;
pRecord->Open("use test SELECT name FROM sys.sysobjects WHERE type='U' ORDER BY name", pConnect.GetInterfacePtr(), adOpenStatic, adLockOptimistic, adCmdText);
while (!pRecord->adoEOF)
{
	vName = pRecord->GetCollect(_variant_t("name"));
	wcout << (TCHAR*)_bstr_t(vName) << endl;
	pRecord->MoveNext();
}
pRecord->Close();

sql语句中前面的"use test"表示在test数据库中查找表后面的“type = 'U' ”表示我们遍历的是用户表此外type 还可以是一下值:

U = 用户表

= 视图, TF = 表函数, P = 存储过程, L = 日志 等

四、遍历某个表中的所有字段:

//显示表中所有的字段名
cout << "test表中所有字段:" << endl;
FieldsPtr fields;//用于保存字段信息
pRecord->Open("SELECT * FROM users", pConnect.GetInterfacePtr(), adOpenStatic, adLockOptimistic, adCmdText);
fields = pRecord->GetFields();//获取字段信息
long nCount = fields->GetCount();//获取遍历到的字段总数
for (int i = 0; i < nCount; i++)
{//获取到的字段信息是放到field对象的item结构体数组中,利用GetItem可以获取该结构体数组中的某一项,利用GetName函数可以获取结构体中存储的字段名
	bstr_t bstrName = (fields->GetItem(_variant_t((long)i)))->GetName();
	TCHAR *pText = static_cast<TCHAR*>(bstrName);//将字段名转化为字符串输出
	wcout << pText << endl;
}

利用以上所有代码,用户可以根据获取到局域网中所有SQL SERVER数据库服务器,遍历其中的所有数据库,根据获取到的数据库获取数据库中所有表,进到某一个表中遍历所有字段,有了字段用户就可以通过SQL语句操作某个表或者其中的某个字段了

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏西安-晁州

mysql随笔

Mysql学习笔记 1、操作数据库 use dataBaseName  //使用数据库 show databases   //显示所有数据库 show tabl...

20600
来自专栏后台架构

Sphinx源码学习笔记(二):查询关键词

 继续上一篇索引创建流程完成,学习理解一下查询关键词的逻辑处理流程。

33260
来自专栏更流畅、简洁的软件开发方式

分页控件之分页算法 —— for SQL Server 版。

上两篇随笔: 我的分页控件(未完,待续)——控件件介绍及思路 我自己写的一个分页控件(源码和演示代码)PostBack分页版 for vs2003、SQL ...

25090
来自专栏企鹅号快讯

浅谈数据库Join的实现原理

Join的实现算法有三种,分别是Nested Loops Join, Merge Join, Hash Join。 DB2、SQL Server和Oracle都...

422100
来自专栏加米谷大数据

Hive的数据类型

本文介绍hive的数据类型,数据模型以及文件存储格式。这些知识大家可以类比关系数据库的相关知识。

17720
来自专栏后端技术探索

mysql5.7强势支持原生json格式!!全面掌握

mysql一直是如此优秀,但是随着最近一些nosql的强劲发展,甚为关系型数据库的mysql,也不例外在某些层面稍有逊色。其中,是否支持json格式是最常被用来...

10220
来自专栏java系列博客

oracle 中start with ... connect by prior 子句的用法

19020
来自专栏信安之路

sql注入学习总结

所谓SQL注入,就是通过把SQL命令插入到Web表单提交或输入域名或页面请求的查询字符串,最终达到欺骗服务器执行恶意的SQL命令。

12700
来自专栏崔庆才的专栏

Python操作MySQL存储,这些你都会了吗?

49350
来自专栏Java帮帮-微信公众号-技术文章全总结

Oracle应用实战八(完结)——存储过程、函数+对象曹组

游标 在写java程序中有结果集的概念,那么在pl/sql中也会用到多条记录,这时候我们就要用到游标,游标可以存储查询返回的多条数据。 游标可以理解为是PL/S...

36760

扫码关注云+社区

领取腾讯云代金券