news 2026/4/15 16:57:19

汇编语言全接触-37.连接数据源

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
汇编语言全接触-37.连接数据源

本教程中,我们将学习使用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:DWORD

SQLRETURN 被定义为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 ?

.code

invoke 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:DWORD

EnvironmentHandle. 与字面意思一样, 它包含了要设置属性的环境句柄.

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 ?

.code

invoke SQLAllocHandle, SQL_HANDLE_ENV, SQL_HANDLE_NULL, addr hEnv

.if ax==SQL_SUCCESS || ax==SQL_SUCCESS_WITH_INFO

invoke 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 ?

.code

invoke SQLAllocHandle, SQL_HANDLE_ENV, SQL_HANDLE_NULL, addr hEnv

.if ax==SQL_SUCCESS || ax==SQL_SUCCESS_WITH_INFO

invoke SQLSetEnvAttr, hEnv, SQL_ATTR_ODBC_VERSION, SQL_OV_ODBC3, NULL

.if ax==SQL_SUCCESS || ax==SQL_SUCCESS_WITH_INFO

invoke SQLAllocHandle, SQL_HANDLE_DBC, hEnv, addr hConn

.if ax==SQL_SUCCESS || ax==SQL_SUCCESS_WITH_INFO

建立一个连接

我们现在要通过特定的ODBC驱动程序来连接数据源.通过这三个ODBC函数来达成这个目标.它们为我们提供了好几层"选择".

SQLConnect

Core

这是最简单的函数。它只需要数据源名(DSN,Data source name)和可选的用户名和密码.它不提供任何GUI选项例如向用户显示一个对话框来提供更多信息。如果你已经有了需要使用的数据库的DSN就可以使用这个函数.

SQLDriverConnect

Core

这个函数提供了较SQLConnect更多的选择.我们可以连接一个没有在系统信息内定义的数据源。如没有DSN.另外,我们可以指定这个函数是否需要显示一个对话框来为用户提供更多信息.例如,如果用户遗漏了数据库的名字,它会指导ODBC驱动程序显示一个对话框,让用户来选择想连接的数据库.

SQLBrowseConnect

Level 1

这个函数允许在运行时(RunTime)枚举数据源.比SQLDriverConnect更加灵活。因为可以多次顺序调用SQLBrowseConnect,而每次提供给使用者更多的专用信息直到最后获得需要的连接句柄.

我将先检查SQLConnect函数.要使用 SQLConnect,你应先知道什么是DSN. DSN是数据源名(Data Source Name)的缩写,是一个唯一标识某数据源的字符串。一个DSN标识了一个包含了如何连接某一特定的数据源的信息的数据结构.这个信息包括要使用何种ODBC驱动程序及要连接哪个数据库.我们可以通过控制面板中的32位ODBC数据源来创建、修改及删除DSN.

SQLConnect的语法如下:

SQLConnect proto ConnectionHandle:DWORD

pDSN:DWORD,

DSNLength:DWORD,

pUserName:DWORD,

NameLength:DWORD,

pPassword:DWORD,

PasswordLength:DWORD

ConnectionHandle. 要使用的连接句柄.

pDSN. 指向DSN的指针.

DSNLength. DSN的长度

pUserName. 指向用户名的指针

NameLength. 用户名的长度

pPassword. 指向该用户名所使用密码的指针

PasswordLength. 密码的长度

在最小情况下, SQLConnect 需要连接句柄,DSN和DSN的长度。如果数据源不需要的话,用户名和密码就不是必须的.函数的返回值与SQLAllocHandle的返回值相同.

假设我们的系统中有一个叫做"Sales" 的DSN并且我们想连接这个数据源.我们可以这样做:

.data

DSN db "Sales",0

.code

......

invoke SQLConnect, hConn, addr DSN, sizeof DSN,0,0,0,0

SQLConnect 的缺点是:在连接一个数据源之前,我们必须创建它的DSN. SQLDriverConnect 提供了更大的灵活性.它的语法如下:

SQLDriverConnect proto ConnectionHandle:DWORD,

hWnd:DWORD,

pInConnectString:DWORD,

InStringLength:DWORD,

pOutConnectString:DWORD,

OutBufferSize:DWORD,

pOutConnectStringLength:DWORD,

DriverCompletion:DWORD

ConnectionHandle连接句柄

hWnd 应用程序窗口句柄.如果这个参数被置为NULL,驱动程序将不会为用户显示一个对话框来显示更多信息(如果有的话).

pInConnectString 指向连接字符串的指针. 这是一个ASCIIZ字符串,格式由要连接的具体ODBC驱动程序描述.它描述了驱动程序名、数据源及其他附加属性.连接字符串的具体描述请参见MSDN,这里不再细述.

InStringLength 连接字符串的长度.

pOutConnectString 指向将要被填入完整连接字符串的缓冲区的指针.这个缓冲区将至少有1,024字节长.这听上去使人困惑。事实上,我们提供的连接字符串会不完整,这时,ODBC驱动程序会提示用户更多信息.接下来ODBC驱动程序会根据所有可能的信息创建一个完整的连接字符串并将其放入缓冲区。即使我们提供的连接字符串已经可以工作了,这个缓冲区也会填入更多的属性值.这个参数的目的是我们可以保存完整连接字符串来为接下来的连接做准备。

OutBufferSize 由pOutConnectString指向的缓冲区的长度.

pOutConnectStringLength 指向一个双字的指针,用来接收由ODBC驱动程序返回的完整连接字符串的长度。

DriverCompletion 一个标志用来指示ODBC管理器/驱动程序是否将提示用户更多信息.但是,这个标志取决于是否在调用本函数时传送了hWnd 参数一个窗口句柄。如果没有,即使该标志被设置,ODBC管理器/驱动程序也不会提示用户.可能值如下:

SQL_DRIVER_PROMPT

ODBC驱动程序提示用户输入信息。驱动程序将利用这些信息来创建连接字符串.

SQL_DRIVER_COMPLETE

SQL_DRIVER_COMPLETE_REQUIRED

仅当用户提供的连接字符串不完全时, ODBC驱动程序才会提示用户.

SQL_DRIVER_NOPROMPT

ODBC驱动程序将不会提示用户.

例子:

.data

strConnect 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

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/15 16:55:39

用Math.abs()快速构建距离计算原型

快速体验 打开 InsCode(快马)平台 https://www.inscode.net输入框内输入如下内容: 开发一个快速原型项目,使用Math.abs()计算:1) 一维数轴两点距离;2) 二维平面直角坐标距离;3) 简化版曼哈顿距离;4) 时间轴…

作者头像 李华
网站建设 2026/4/15 13:30:45

【Open-AutoGLM短视频辅助神器】:揭秘AI全自动采集剪辑背后的黑科技

第一章:Open-AutoGLM短视频辅助神器概述Open-AutoGLM 是一款专为短视频内容创作者设计的智能化辅助工具,融合了自然语言处理、视觉生成与自动化流程编排能力,旨在提升内容生产效率与创意表达质量。该系统基于 GLM 大语言模型架构,…

作者头像 李华
网站建设 2026/4/15 13:30:34

揭秘Open-AutoGLM智能发票处理:如何3分钟完成报销单自动整理

第一章:揭秘Open-AutoGLM智能发票处理的核心价值Open-AutoGLM 是一款基于大语言模型与自动化流程引擎深度融合的智能文档处理平台,专注于解决企业级发票识别、分类与结构化提取中的复杂挑战。其核心价值在于将非标准化的发票数据转化为高精度、可操作的结…

作者头像 李华
网站建设 2026/4/15 13:31:44

FaceFusion支持FFmpeg深度集成,编码无压力

FaceFusion 深度集成 FFmpeg:让 AI 视频处理真正“无压力” 在短视频工厂日夜不停转、虚拟偶像频繁登台的今天,内容创作者面临的挑战早已不止于“有没有创意”,更在于“能不能快速交付”。尤其是涉及人脸替换这类高算力需求的任务——你可能训…

作者头像 李华
网站建设 2026/4/11 17:00:09

创芯科技USB-CAN分析仪驱动安装全攻略:新手快速上手指南 [特殊字符]

创芯科技USB-CAN分析仪驱动安装全攻略:新手快速上手指南 🚀 【免费下载链接】创芯科技USB-Can分析仪驱动 本仓库提供创芯科技USB-Can分析仪的驱动程序,该驱动程序专为配合Can-Test软件使用而设计。通过安装此驱动,用户可以顺利连接…

作者头像 李华
网站建设 2026/4/15 8:17:21

彻底掌握X-editable与Select2集成:构建企业级在线编辑下拉框

彻底掌握X-editable与Select2集成:构建企业级在线编辑下拉框 【免费下载链接】x-editable vitalets/x-editable: 是一个用于实现表单字段在线编辑的jQuery插件,可以方便地在Web应用中实现表单字段的在线编辑。适合对jQuery、表单编辑和想要实现表单在线编…

作者头像 李华