前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >ADO对SQL Server 2008数据库的基础操作

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

作者头像
Masimaro
发布2018-08-31 15:56:01
8220
发布2018-08-31 15:56:01
举报

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

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

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

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

代码语言:javascript
复制
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下来的,只是修改了小部分代码:

代码语言:javascript
复制
#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);//释放内存空间
	}
}
代码语言:javascript
复制
代码语言:javascript
复制
代码语言:javascript
复制
代码语言:javascript
复制

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

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

代码语言:javascript
复制
//初始化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;
}
代码语言:javascript
复制
代码语言:javascript
复制

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

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

代码语言:javascript
复制
//遍历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 = 日志 等

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

代码语言:javascript
复制
//显示表中所有的字段名
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语句操作某个表或者其中的某个字段了

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2017-10-24 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
数据库专家服务
数据库专家服务(Database Expert Service,DBexpert)为您提供专业化的数据库服务。仅需提交您的具体问题和需求,即可获得腾讯云数据库专家的专业支持,助您解决各类专业化问题。腾讯云数据库专家服务团队均有10年以上的 DBA 经验,拥有亿级用户产品的数据库管理经验,以及丰富的服务经验。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档