【梳理】数据库系统概论 第8章 数据库编程 8.1 嵌入式SQL 8.2 过程化SQL 8.3 存储过程和函数 8.4 ODBC编程

教材:王珊 萨师煊 编著 数据库系统概论(第5版) 高等教育出版社
注:文档高清截图在后

第8章 数据库编程

标准SQL是非过程化的查询语言,操作统一、面向集合、功能丰富、使用简单。非过程化语言是相对于过程化语言而言的,语言的使用者只需给出输入,计算机执行并输出,使用者无需干预执行过程。相对地,关系代数是过程化的,使用者必须一步一步指定执行过程。高度非过程化的语言的一个弱点是:缺少流程控制能力,难以实现应用中的逻辑控制。SQL编程技术可以有效克服SQL语言的复杂应用的不足,提高应用系统和DBMS的互操作性。

8.1 嵌入式SQL

1、嵌入式SQL,是指将SQL语句包含到程序设计语言中去。被嵌入的程序设计语言,如C / CPP / Java等,称为宿主语言,简称主语言。对嵌入式SQL,DBMS一般采用预编译方法处理,即DBMS的预处理程序对源程序扫描,识别出嵌入式SQL语句并转换成主语言的语句,主语言的编译器就能识别它们并连通代码的其它部分进行编译。
对编程语言的语法部分的细节不会被写入本归纳梳理中。

2、SQL通信区(SQL Communication Area,SQLCA)是一片内存空间,主要包括描述当前工作状态和运行环境的各种数据。SQL语句执行后,相应的信息会传入SQLCA。应用程序据此决定接下来的执行语句。SQLCA中的变量SQLCODE存放每次执行SQL语句后返回的代码。每执行完一条SQL语句,都应该测试SQLCODE的值,了解执行情况并作相应处理。一般而言0为成功,非0为出错。程序员可以根据SQLCODE的错误代码查找问题。

3、嵌入式SQL语句可以使用整份代码的SQL语句以外的变量,即主语言的程序变量来输入输出。SQL语句中使用的来自主语言程序的变量简称主变量(host variable),分为输入主变量和输出主变量。输入主变量由应用程序赋值,SQL语句引用;输出主变量由SQL语句赋值或设置状态信息,返回给应用程序。
一个主变量可附带一个任选的指示变量(indicator variable),它是整型的,用于“指示”所指主变量的值或条件。例如:指示输入主变量是否为空,检测输出主变量是否为空,值是否被截断。

4、SQL面向集合,一条SQL语句可以产生或处理多条记录;主语言是面向记录的,一组主变量一次只能存放一条记录。嵌入式SQL引入了游标(cursor),通过在多条记录中移动游标,可以将指向的记录传给主变量。游标的本质是数据缓冲区,存放SQL语句的执行结果。每个游标区都有命名。

5、嵌入式SQL程序访问数据库时必须首先连接数据库,RDBMS根据用户信息对连接进行合法性验证,通过身份验证才能建立可用的合法连接。当某个连接上的所有数据库操作完成后,应用程序应该主动释放占用的连接资源。

6、当嵌入式SQL语句中使用的主变量、查询的目标列和条件等都是固定的时候,SQL语句属于静态SQL语句。而某些应用可能需要在执行过程中才能确定需要执行的SQL语句和查询的条件,这时候需要使用动态SQL语句解决这类问题。动态SQL方法允许在程序运行过程临时“构造”SQL语句。动态SQL支持动态组装SQL语句和动态参数两种形式,给开发者提供设计任意SQL语句的能力。

8.2 过程化SQL

1、基本的SQL是高度非过程化的语言。嵌入式SQL将SQL语句嵌入了程序设计语言,借助高级语言的控制功能实现过程化。过程化SQL是对SQL的扩展,使其增加了过程化语句功能。过程化SQL程序的基本结构是块。块之前可以互相嵌套,每个块完成一个逻辑操作。

2、过程化SQL提供了流程控制语句,主要由条件控制语句和循环控制语句。这些语句的语法语义和一般的高级语言类似,使用时应该参照具体数据库产品的语法规则。

3、如果过程化SQL在执行时出现一次,应该让程序在异常处暂停,执行异常处理语句。错误处理也需要根据具体系统的支持情况来进行。

8.3 存储过程和函数

1、过程化SQL块主要有两种类型:命名块和匿名块。匿名块每次执行时都需要编译,不能被存储到数据库中,也不能在其它过程化SQL块中调用。过程和函数是命名块,编译后存在数据库中,称为持久性存储模块(Persistent Stored Module,PSM),可以反复调用,运行较快。

2、存储过程是由过程化SQL语句书写的过程,经编译和优化后存储在数据库服务器中,使用时只需调用即可。

3、存储过程的优点:
(1)不像解释执行的SQL语句那样在提出请求时才进行语法分析和优化,因而运行效率高。它提供了在服务器端快速执行SQL语句的有效途径。
(2)降低客户端和服务器的通信量。客户端的应用程序只需通过网络发送调用存储过程的名称和参数,就可以让RDBMS执行其中的多条SQL语句并进行数据处理,仅返回最终结果到客户端。
(3)方便实施企业规则。可以把企业规则的运算程序写成存储过程放入数据库的服务器中,由RDBMS管理,既利于集中控制又方便维护。当企业规则变化时只需修改存储过程,无需修改其它应用程序。

4、函数也称自定义函数,因为是用户自己使用过程化SQL时定义的。函数也是持久性存储模块,定义和存储过程类似,但必须指定返回类型。

8.4 ODBC编程

1、提出和产生ODBC的原因是:存在不同的DBMS。
目前广泛使用的RDBMS有很多,尽管都属于关系数据库,也都遵循SQL标准,但不同的系统仍有众多差异。因此,某个RDBMS下编写的应用程序并不能在另一RDBMS下运行,适应性和可移植性较差。例如:Oracle上运行的应用系统要在KingbaseES上运行,就必须进行修改移植。移植过程一般是繁琐的,开发人员必须清楚不同RDBMS的各种区别,细心地一一修改、测试。
但更重要的是,许多应用程序需要共享多部门的数据,访问不同的RDBMS。谓词,人们开始研究开发连接不同RDBMS的方法、技术和软件,使数据库系统开放,实现数据库互连。ODBC(Open Database Connectivity,开放数据库互连)是Microsoft推出的接口标准,属于Microsoft的开放服务体系(Windows Open Services Architecture,WOSA)的有关数据库的一个部分。它建立了一组规范,并提供一组访问数据库的API(应用程序编程接口,Application Programming Interface)。ODBC具有两重功效或约束力:规范应用开发、规范RDBMS应用接口。

2、ODBC应用系统由4部分组成:用户应用程序、ODBC驱动程序管理器、数据库驱动程序、数据源(如RDBMS和数据库)。

3、用户应用程序提供UI(用户界面)、应用逻辑和事务逻辑。使用ODBC开发数据库应用程序时,应用程序调用的是标准的ODBC函数和SQL语句。应用层使用ODBC API与数据库交互。使用ODBC开发应用系统的程序,简称ODBC应用程序,包括:
·请求连接数据源。
·向数据源法搜你SQL语句。
·为SQL语句执行结果分配存储空间,定义所读取的数据格式。
·获取数据库操作结果或处理错误。
·进行数据处理并向用户提交处理结果。
·请求事务的提交和回滚操作。
·断开与数据源的连接。

4、ODBC驱动程序管理器用于管理各种驱动程序。ODBC驱动程序管理器由Microsoft提供,包含在ODBC32.DLL中,对用户透明,管理应用程序和驱动程序的通信。ODBC驱动程序管理器的主要功能包括:装在ODBC驱动程序、选择和连接正确的驱动程序、管理数据源(建立、配置或删除)、检查ODBC调用参数的合法性,以及记录ODBC函数的调用等。当应用层需要时,还可以返回驱动程序的有关信息。ODBC驱动程序管理器还可以查看当前安装的数据库ODBC驱动程序。

5、ODBC通过数据库驱动程序提供应用系统与数据库平台的独立性。
ODBC应用程序不能直接存取数据库,其各种操作请求由驱动程序管理器提交给某个RDBMS的ODBC驱动程序,通过调用驱动所支持的函数存取数据库。数据库的操作结果也通过驱动返回给应用程序。如果应用程序要操作不同的数据库,就要动态链接到不同的驱动程序上。
目前,ODBC驱动程序主要由单束和多束两类。单束一般是数据源和应用程序在同一台机上,驱动直接完成对数据文件的IO。这时驱动相当于数据管理器。多束驱动支持客户端-服务器(C-S Architecture)、客户端-应用服务器/数据库服务器等网络环境下的数据访问,这时由驱动完成数据库访问请求的提交和结果集接受,应用程序使用驱动提供的结果集管理接口操纵执行后的结果数据。

6、数据源是最终用户需要访问的数据,包含数据库位置和数据库类型等信息,实际上是一种数据连接的抽象。ODBC给每个被访问的数据源指定唯一的数据源名(Data source name,DSN),并映射到所有必要的、用来存储数据的低层软件。在连接中,用DSN代表用户名、服务器名、所连接的数据库名等。最终用户无需知道DBMS或其它数据管理软件、网络及有关ODBC驱动的细节,数据源的最终用户是透明的。
例如:某校在MySQL和SQL Server上各创建一个数据库:学术活动数据库、文艺活动数据库。学校的信息系统要从这两个数据库中存取数据。为方便地与两个数据库连接,为这两个数据库分别创建DSN:AcademicEvents和LAEvents。此后,要访问相应的数据库,只需与AcademicEvents和LAEvents连接即可,无须记住驱动程序、服务器名、数据名等。所以,在开发ODBC数据库应用程序时,首先要为相应的DBMS或数据库建立数据源并命名。

7、各数据库厂商的ODBC API都要符合两方面的一致性:
·API一致性,包括核心级、扩展1级、扩展2级。
·语法一致性,包含最低限度SQL语法级、核心SQL语法级、扩展SQL语法级。

8、ODBC不同版本的函数和函数使用是由差异的,必须注意使用的版本。

9、句柄(handle)是一个对象的唯一标示,和对象一一对应。ODBC中的句柄包括:
(1)环境句柄。每个ODBC应用需要建立一个ODBC环节,分配一个环境句柄,通过句柄存取数据的全局背景,如环境状态、当前环境状态诊断、当前在环境上分配的连接句柄等。
(2)通过一个环境句柄可以在环境中建立多个连接句柄。每一个连接句柄实现与一个数据源之间的连接。
(3)一个连接中还可以建立多个语句句柄,它不只是对应SQL语句,还包括SQL语句产生的结果集以及相关信息等。
(4)通过描述符句柄,可以获得描述SQL语句的参数、结果集列的元数据集合。

10、ODBC定义了两套数据类型,即SQL数据类型和主语言的数据类型。SQL数据类型用于数据源,主语言数据类型用于应用程序的主语言代码。应用程序可以通过SQLGetTypeInfo来获取不同的驱动对数据类型的支持状况。
(本条以下部分给出课本的描述和Microsoft的描述,两者存在冲突,我会继续查证)
课本内容:
SQL数据通过SQLBindcol从结果集列返回到应用程序变量;如果SQL语句含有参数,应用程序为每个参数调用SQLBindParameter,并把它们绑定至应用程序变量。
Microsoft的描述:
SQLBindCol 函数
符合性
引入的版本:ODBC 1.0 标准符合性:ISO 92
摘要
SQLBindCol将应用程序数据缓冲区绑定到结果集中的列。
Conformance
Version Introduced: ODBC 1.0 Standards Compliance: ISO 92
Summary
SQLBindCol binds application data buffers to columns in the result set.
SQLBindParameter 函数
符合性
版本引入了:ODBC 2.0 标准符合性:ODBC
摘要
SQLBindParameter将缓冲区绑定到的 SQL 语句中的参数标记。 SQLBindParameter支持绑定到 Unicode 的 C 数据类型,即使基础驱动程序不支持 Unicode 数据。
Conformance
Version Introduced: ODBC 2.0 Standards Compliance: ODBC
Summary
SQLBindParameter binds a buffer to a parameter marker in an SQL statement. SQLBindParameter supports binding to a Unicode C data type, even if the underlying driver does not support Unicode data.

11、使用ODBC的应用系统的大致工作流程:
【1】配置数据源。
配置数据源有两种方法:
(1)运行数据源管理工具。
(2)使用驱动程序管理器提供的ConfigDsn函数来对数据源增删改。此方法特别实用于在应用中创建的临时数据源。
【2】初始化环境。
由于还没有和具体的驱动关联,所以不是由具体的DBMS驱动来管理,而是由驱动管理器来控制并配置环境。直到应用程序通过调用连接函数和某个数据源连接后,驱动管理器才调用所连的驱动中的SQLAllocHandle来真正分配环境句柄的数据结构。
【3】建立连接。
分配连接句柄后,通过相应的连接函数来与数据源连接。一般至少要提供DSN、UID和口令作为连接的参数。
【4】分配语句句柄。
处理任何SQL语句之前,应用程序需要首先分配一个语句句柄。语句句柄指向具体的SQL语句和输出的结果集等信息。还可以通过SQLtStmtAttr更改语句属性。
【5】执行SQL语句。
应用程序处理SQL语句的方式有两种:预处理和直接执行。执行后,对于有结果集的语句,进行结果集处理;否则,可以直接利用本语句的句柄执行新语句或获取行计数(执行影响的行数)之后继续执行。
【6】结果集处理。
应用程序获取结果集的列数、每一列的名称、数据类型、精度、范围等。对信息明确的函数,可以省略这些获取过程。
ODBC使用游标处理结果集数据。Forward-only游标只能向前滚动,是ODBC的默认游标类型。Scroll游标则分为静态(static)、动态(dynamic)、码集驱动(keyset-driven)和混合型(mixed)四种。
ODBC游标的打开方式与嵌入式SQL不同,不是显式声明而是系统自动产生。结果集刚刚生成时,游标指向第一行数据之前。应用程序先将结果绑定到应用程序的缓冲区,再移动游标获取结果集的每一行。对于图像等特别的数据类型,一个缓冲区不足以容纳所有数据时,可以分多次获取内容。最后,需要通过SQLClosecursor关闭游标。
【7】中止处理。
处理结束后,应用程序释放语句句柄,然后释放数据库连接并与数据库服务器断开,最后释放ODBC环境。

【梳理】数据库系统概论 第8章 数据库编程 8.1 嵌入式SQL 8.2 过程化SQL 8.3 存储过程和函数 8.4 ODBC编程【梳理】数据库系统概论 第8章 数据库编程 8.1 嵌入式SQL 8.2 过程化SQL 8.3 存储过程和函数 8.4 ODBC编程【梳理】数据库系统概论 第8章 数据库编程 8.1 嵌入式SQL 8.2 过程化SQL 8.3 存储过程和函数 8.4 ODBC编程【梳理】数据库系统概论 第8章 数据库编程 8.1 嵌入式SQL 8.2 过程化SQL 8.3 存储过程和函数 8.4 ODBC编程【梳理】数据库系统概论 第8章 数据库编程 8.1 嵌入式SQL 8.2 过程化SQL 8.3 存储过程和函数 8.4 ODBC编程【梳理】数据库系统概论 第8章 数据库编程 8.1 嵌入式SQL 8.2 过程化SQL 8.3 存储过程和函数 8.4 ODBC编程【梳理】数据库系统概论 第8章 数据库编程 8.1 嵌入式SQL 8.2 过程化SQL 8.3 存储过程和函数 8.4 ODBC编程【梳理】数据库系统概论 第8章 数据库编程 8.1 嵌入式SQL 8.2 过程化SQL 8.3 存储过程和函数 8.4 ODBC编程【梳理】数据库系统概论 第8章 数据库编程 8.1 嵌入式SQL 8.2 过程化SQL 8.3 存储过程和函数 8.4 ODBC编程