专栏首页MasiMaro 的技术博文ADO对SQL Server 2008数据库的基础操作

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 条评论
登录 后参与评论

相关文章

  • OLEDB事务

    学过数据的人一般都知道事务的重要性,事务是一种对数据源的一系列更新进行分组或者批处理以便当所有更新都成功时同时提交更新,或者任意一个更新失败时进行回滚将数据库中...

    Masimaro
  • 算法与数据结构(二):链表

    上一篇简单的开了一个头,简单介绍了一下所谓的时间复杂度与空间复杂度,从这篇开始将陆陆续续写一下常用的数据结构:链表、队列、栈、树等等。 链表当初是我在学校...

    Masimaro
  • windows 安全模型简介

    操作系统中有些资源是不能由用户代码直接访问的,比如线程进程,文件等等,这些资源必须由系统级代码由RING3层进入到RING0层操作,并且返回一些标识供用户程序使...

    Masimaro
  • Angular的scope. apply和CRM WebClient UI的modify方法

    在每一次Javascript代码执行序列执行结束后,Angular都去检查绑定的数据是否发生改变,通过调用scope.apply完成。scope. apply最...

    Jerry Wang
  • 89 次荣登活跃榜,最高排名第 9 ,从零学算法第二周周报发布

    当搜索一个键时,哈希表使用相同的哈希函数来查找对应的桶,并只在特定的桶中进行搜索。

    double
  • The Clean Architecture in PHP 读书笔记(七)

    MVC的关键是给我们提出了一个原则:怎么对项目进行合理的关注点分离。Model负责业务领域,controller负责对model进行工作安排,而view则负责门...

    zhuanxu
  • mysql导入数据库文件最大限制更改解决方法

    用户1272546
  • mysql导入数据库文件最大限制更改解决方法

    下午用phpmyadmin导入mysql数据库时,我的远远大于2M数据库不能导入,mysql数据库最大只能导入2M..

    用户1191760
  • 小心!做 UI 自动化一定要跨过这些坑

    “才刚写完用例,怎么开发大哥又改了UI了?” “维护这些破用例的时间,都够我手工测三遍了,真的有意义么?” “这破手机,能不能别老是系统弹框……”

    陈帅
  • 小心!做UI自动化一定要跨过这些坑

    一、引子 UI自动化,在移动互联网时代的今天,一直都是在各大测试测试社区最为火爆的一个TOPIC。甚至在测试同行面前一提起自动化,大家就会自然而然的问:“恩,...

    腾讯移动品质中心TMQ

扫码关注云+社区

领取腾讯云代金券