目录

1. SQL

1.1. SQL简介

1.2. SQL语句概述

1.3. 优化器概述

1.4. SQL处理概述

2. PLSQL

2.1. 服务器端编程简介

2.2. PL/SQL概述

2.3. PL/SQL包

2.4. 触发器概述


1. SQL

本章概述结构化查询语言(SQL)以及KingbaseES数据库如何处理SQL语句。

本章包括以下主题:

  • SQL简介

  • SQL语句概述

  • 优化器概述

  • SQL处理概述

1.1. SQL简介

SQL是基于集合的高级别声明性计算机语言,所有程序和用户都使用它来访问数据库中的数据。虽然某些KingbaseES图形化工具和应用程序隐藏了 SQL 的使用, 但实际上所有的后台数据库操作都是使用 SQL 执行的。

SQL 提供一个对关系数据库如KingbaseES数据库的接口。 SQL可以执行以下任务:

  • 创建、替换、改变、和删除对象

  • 插入、 更新、 和删除表行

  • 查询数据

  • 控制对数据库及其对象的访问

  • 保证数据库的一致性和完整性

SQL 可以交互地使用即将语句手动地输入到程序,也可以嵌入到不同的语言(如 C 或 Java) 编写的程序内。

1.1.1. SQL数据访问

目前,计算机语言分两类派别:非过程化的声明性语言,它描述应该做什么;过程化语言,如 C + + 和 Java,它描述如何做。 SQL 是声明性的语言,用户指定他们想要的结果,而不必说明如何得到它。数据库的工作是生成一个过程,来操作数据和检索请求的结果。SQL的声明使您能够在逻辑层面使用数据,仅当您想要处理该数据时,才需要关注其实现细节。

数据库用一个单一步骤检索满足 WHERE 条件的所有行。这些行可以作为一个整体传递给用户,或者其他SQL 语句和应用程序。您不需要一行一行地处理,您也不需要知道行是如何被物理存储和检索的。所有 SQL 语句都使用优化器来处理,优化器会确定访问指定数据最有效的方式。KingbaseES 数据库还支持其它多种技术,可以使优化器更好地执行其工作。

1.1.2. SQL标准

KingbaseES遵循行业认可的标准。被行业认可的委员会包括美国国家标准协会 (ANSI) 和国际组织的标准化(ISO)。 ANSI 和 ISO/IEC 都已规定SQL 作为关系数据库的标准语言。

1986年10月,美国国家标准协会 (ANSI) 将 SQL 作为关系数据库管理系统的标准语言,制定了ANSI SOL 标准。随后,国际标准化组织 ISO 也颁布了ISO SQL国际标准。随着数据库技术的发展,后续推出了一系列的SQL标准 ,如SQL-89,SQL-92,SQL:1999,SQL:2003,SQL:2016等。中国的标准化机构也参考国际标准制定了一系列的数据库标准。

目前,KingbaseES的SQL语言遵循SQL:1992入门级和过渡级标准、SQL:1999和SQL:2003的核心级标准、SQL:2016最新标准,并在此基础上进行了适当的扩充。没有特殊说明情况下,KingbaseES数据库中的语句都遵循 SQL 标准。KingbaseES数据库提供了一些其他语句工具,KSQL和数据库对象管理工具,使您能够在 KingbaseES 数据库上运行任何 ANSI/ISO 标准 SQL 语句,以及其他语句或函数。

1.2. SQL语句概述

在 KingbaseES 数据库中执行的所有操作都是使用 SQL 语句来执行的。SQL 语句是一种计算机指令,它包含标识符、参数、变量、名称、数据类型、和 SQL 的保留字。

SQL 语句必须是一个完整的 SQL 句子,例如:

SELECT ORDERID, CUSTOMERID,ORDERDATE FROM ORDERS;

KingbaseES数据库仅运行完整的 SQL 语句。像执行下面这样的语句将报错:

SELECT ORDERID;SQL错误[42703]:错误:字段“ORDERID”不存在

1.2.1. 数据定义语言 (DDL) 语句

数据定义语言 (DDL) 语句定义、更改、和删除模式对象。DDL 能够更改对象的属性, 而无需更改访问该对象的应用程序。您还可以在当数据库用户正在数据库中执行操作时,使用 DDL 更改对象的结构。

DDL 语句可以执行以下任务:

  • 创建、更改、和删除模式对象和其他数据库结构,包括数据库本身和数据库用户。大部分的 DDL 语句以关键字 CREATE、ALTER、或 DROP 开头。

  • 删除模式对象中的所有数据,而不删除这些对象的结构(TRUNCATE) 。

  • 授予和撤消权限和角色 (GRANT, REVOKE) 。

  • 打开和关闭审核选项 (AUDIT , NOAUDIT) 。

  • 将注释添加到数据字典 (COMMENT)。

如下例子使用 DDL 语句来创建 ORDERS 表,插入数据,再使用 DDL 更改表结构、授予和撤消用户在该表上的权限,然后删除表:

CREATE TABLE ORDERS
(ORDERID INT4 CONSTRAINT PK_ORDERS PRIMARY KEY,CUSTOMERID VARCHAR(10) NOT NULL,ORDERDATE DATE
);INSERT INTO ORDERS VALUES(100,'KINGBASE','2000-01-01');
ALTER TABLE ORDERS ADD COLUMN EMPLOYEEID INT4;
GRANT INSERT ON ORDERS TO PUBLIC;
REVOKE INSERT ON ORDERS FROM PUBLIC;
DROP TABLE ORDERS;

在数据库执行 DDL 语句之前会立即执行一个隐式提交,之后立即执行一个提交或回滚。再上面的示例中,INSERT 语句后面跟了一个 ALTER TABLE 语句, 因此数据库会提交这个INSERT 语句。如果 ALTER TABLE 语句成功, 则数据库提交此语句 ;否则,数据库回滚此语句。在任一情况下,这个INSERT 语句都是已经提交的。

1.2.2. 数据操纵语言 (DML)

数据操纵语言 (DML) 语句查询或操作模式对象中的数据。DDL 语句可以更改对象的结构,而 DML 语句使您能够查询或更改其内容。例如,ALTER TABLE 更改一个的表的结构,而 INSERT 向表中添加一个或多个行。

DML 语句是最经常使用的 SQL 语句,它可以执行以下任务:

  • 从一个或多个表或视图,检索或获取数据(SELECT) 。

  • 通过指定一个列值列表,或使用一个子查询,来选择和操作现有数据,以将新的数据行添加到表中(INSERT)。

  • 更改表或视图中的现有行中的值(UPDATE)。

  • 更新或有条件地将行插入到表或视图 (MERGE)。

  • 从表或视图中删除行(DELETE)。

  • 查看 SQL 语句的执行计划(EXPLAIN PLAN) 。

  • 锁定一个表或视图,临时限制其他用户的访问(LOCK TABLE) 。

下面的示例使用 DML 来查询ORDERS表,插入数据行、更新然后将其删除:

CREATE TABLE ORDERS
(ORDERID INT4 CONSTRAINT PK_ORDERS PRIMARY KEY,CUSTOMERID VARCHAR(10) NOT NULL,EMPLOYEEID INT4,ORDERDATE DATE
);
SELECT * FROM ORDERS;
INSERT INTO ORDERS(ORDERID, CUSTOMERID, EMPLOYEEID, ORDERDATE)VALUES(101,'RDJC',1,'1999-03-20');
UPDATE ORDERS SET EMPLOYEEID=2 WHERE ORDERID=101;
DELETE FROM ORDERS WHERE ORDERID=101;

一个事务是一个逻辑工作单元的DML语句的集合。例如,一个学生选课事务可能涉及三个独立的操作:学生查询课程计划、学生添加选课、课表中添加学生记录。与 DDL 的语句不同的是,DML 语句不会隐式提交当前事务。

1.2.2.1. SELECT 语句

查询是一个从表或视图中检索数据的操作。

SELECT 是你唯一可用于查询数据的 SQL 语句。从执行 SELECT 语句检索到的数据集被称为结果集。

下表显示了在一个 SELECT 语句中两个必需的关键字,和两个常见的关键字。该表也说明了这些关键字在 SELECT 语句中的功能。

表 1 SELECT 语句

关键字

必需

描述

功能

SELECT

指定应在结果中显示哪些列。投影会生成表中所包含列的一个子集。表达式是一个或多个值、操作符、和SQL函数的组合。 经过计算后最终得到一个值。出现在SELECT关键字之后,和在FROM子句之前的表达式列表,叫做选择列表

映射

FROM

指定应从哪些或表视图中检索数据。

联接

WHERE

指定一个条件来筛选行,以生成表中的行的一个子集。条件指定一个或多个表达式和逻辑(布尔)运算符的组合, 并返回一个值(TRUE、FALSE、或 UNKNOWN)。

选择

ORDERBY

指定行应以何种顺序显示。

排序

1.2.2.2. 连接

连接是联合两个或多个表、 视图或物化视图中的行的查询。例如,将CUSTOMERS表与 ORDERS 表联接(FROM 子句),只选择满足指定条件的行(WHERE 子句),并使用投影从两个列中检索数据(SELECT)。该 SQL 语句的示例输出如下所示:

CREATE TABLE ORDERS
(ORDERID INT4 CONSTRAINT PK_ORDERS PRIMARY KEY,CUSTOMERID VARCHAR(10) NOT NULL,EMPLOYEEID INT4,ORDERDATE DATE
);
INSERT INTO ORDERS VALUES(101,'RDJC',1,'1999-03-20');CREATE TABLE CUSTOMERS
(CUSTOMERID VARCHAR(10) CONSTRAINT PK_CUSTOMERS PRIMARY KEY,COMPANYNAME VARCHAR(30) NOT NULL,CITY VARCHAR(20)
);
INSERT INTO CUSTOMERS VALUES('RDJC','Bejing Renda Jingcang','BEIJING');SELECT ORDERID,ORDERDATE,COMPANYNAMEFROM ORDERS,CUSTOMERSWHERE CUSTOMERS.CUSTOMERID = ORDERS.CUSTOMERIDAND CUSTOMERS.CUSTOMERID='RDJC';ORDERID |ORDERDATE  |COMPANYNAME               |
--------|-----------|--------------------------|
101     |1999-03-20 |Bejing Renda Jingcang     |

大多数连接在 FROM 子句或者WHERE 子句中都至少有一个连接条件,用于比较不同表的两个列。数据库匹配成对的行,每对包含来自不同表的行,选择这些行连接条件计算结果为TRUE的。优化器基于连接条件、 索引和任何可用的表统计信息,来确定数据库中联接表的顺序。

联接类型包括以下:

  • 内连接

内连接是两个或更多表的联接, 只返回满足连接条件的行。例如,如果连接条件是 CUSTOMERS.CUSTOMERID = ORDERS.CUSTOMERID,则不满足此条件的行不被返回。

  • 外连接

外连接返回所有满足联接条件的行,也返回一个表中不满足与另一个表的连接条件的行。

左外连接的结果始终返回了左表的所有记录,即使联接条件不匹配右表的记录。如果右表匹配的行不存在,那么右表列返回null值。例如,如果存在订单表中的客户编号,在客户表中无记录,ORDERS(左表)和CUSTOMERS(右表)的左外连接检索订单表中的所有行,即使客户表中没有行满足连接条件。

右外连接的结果始终返回右表的所有记录,即使联接条件不匹配左表的记录。如果左表匹配的行不存在,那么左表列返回null值。例如,如果存在客户表中的客户编号,在订单表中无记录,客户表(左表)和订单表(右表)的右外连接检索客户表中的所有行,即使订单表中没有行满足连接条件。

完全外连接是左外连接和右外连接的组合。

  • 笛卡儿积

如果两个表联接查询中的没有联接条件,则数据库返回其笛卡儿积。一个表中的每一行与另一个表中的每一行联合。例如,如果ORDERS表有800行,而CUSTOMERS表有500行,则其笛卡儿积包含800x500行。笛卡儿积是很少用到的。

1.2.2.3. 子查询

子查询是嵌套在另一个 SQL 语句中的 SELECT 语句。 当您必须执行多个查询来解决一个问题时,子查询非常有用。一个语句每个查询部分称为一个查询块。例如,在如下查询中,括号内的子查询是内部查询块:

CREATE TABLE ORDERS
(ORDERID INT4 CONSTRAINT PK_ORDERS PRIMARY KEY,CUSTOMERID VARCHAR(10) NOT NULL,EMPLOYEEID INT4,ORDERDATE DATE
);
INSERT INTO ORDERS VALUES(101,'RDJC',1,'1999-03-20');CREATE TABLE CUSTOMERS
(CUSTOMERID VARCHAR(10)CONSTRAINT PK_CUSTOMERS PRIMARY KEY,COMPANYNAME VARCHAR(30) NOT NULL,CITY VARCHAR(20)
);
INSERT INTO CUSTOMERS VALUES('RDJC','Bejing Renda Jingcang','BEIJING');SELECT  ORDERID, CUSTOMERID, EMPLOYEEID, ORDERDATE FROM  ORDERSWHERE CUSTOMERID IN (SELECT CUSTOMERID FROM CUSTOMERS WHERE CITY='BEIJING' );

子查询SELECT语句检索客户所在城市为北京的客户编号。这些客户编号需要在外部查询块中用到,外部查询基于子查询提供客户编号来检索订单记录。

SQL 语句的结构不会强制数据库必须首先执行内部查询。 数据库可能会重写整个查询,始终由优化器确定用于检索请求行的最佳步骤序列。

1.2.2.4. 事务控制语句

事务控制语句管理 DML 语句所做的更改, 和将多个 DML 语句按事务分组。

事务控制语句可以执行以下任务:

  • 使一个事务的更改持久化(COMMIT)。

  • 撤消在一个事务中自事务开始以来的更改(ROLLBACK) ,或自一个保存点以来的更改(ROLLBACK TO SAVEPOINT)。 保存点是在一个事务上下文中由用户声明的中间标记。

  • 设置一个你可以回滚到的点(SAVEPOINT)。

  • 设定一个事务的特性(SET TRANSACTION) 。

  • 指定是在每个 DML 语句之后、 还是在事务时提交后,执行可延迟完整性约束检查(SET CONSTRAINT)。

下面示例创建一个保存点,然后回滚事务到保存点。该事务将向ORDERS表插入ORDERID为100的值,但不会插入102的值。

CREATE TABLE ORDERS
(ORDERID INT4 CONSTRAINT PK_ORDERS PRIMARY KEY,CUSTOMERID VARCHAR(10) NOT NULL,EMPLOYEEID INT4,ORDERDATE DATE
);BEGIN;INSERT INTO ORDERS(ORDERID,CUSTOMERID,ORDERDATE) VALUES(100,'KINGBASE','2000-01-01');
SAVEPOINT MY_SAVEPOINT;
INSERT INTO ORDERS(ORDERID,CUSTOMERID,ORDERDATE) VALUES(102,'KINGBASE','2000-03-01');
ROLLBACK TO SAVEPOINT MY_SAVEPOINT;
COMMIT;

1.2.2.5. 会话控制语句

会话控制语句动态地管理用户会话的属性。会话是数据库实例内存中的一个逻辑实体, 表示登录到数据库中的一个当前用户的状态。 会话从该用户通过数据库验证开始, 一直持续到用户断开连接或退出数据库应用程序。

会话控制语句能执行以下任务:

  • 通过执行一项专门的功能来改变当前会话属性(SET SESSION)。

  • 启用和禁用角色,它是一组用于当前会话的权限(SET ROLE) 。

例如:下面的语句将会话的时区设置为意大利:

SET TIME ZONE 'Europe/Rome';

1.2.2.6. 系统控制语句

系统控制语句更改数据库实例的属性。KingbaseES数据库通过执行一些系统函数来实现系统控制,默认情况下这些函数只能被超级用户使用。它使您能够更改系统设置,例如,终止一个会话、切换日志文件和重载系统配置文件,如下表所示:

表 2 系统控制语句

名称

返回类型

描述

sys_cancel_backend(pidint)

boolean

取消一个后端的当前查询。如果调用角色是被取消后端的拥有者角色的成员或者调用角色已经被授予sys_signal_backend, 这也是允许的,不过只有超级用户才能取消超级用户的后端。

sys_reload_conf()

boolean

导致服务器进程重载它们的配置文件

sys_rotate_logfile()

boolean

切换服务器的日志文件

sys_terminate_backend(pidint)

boolean

中止一个后端。如果调用角色是被取消后端的拥有者角色的成员或者调用角色已经被授予sys_signal_backend, 这也是允许的,不过只有超级用户才能取消超级用户的后端。

1.2.2.7. 更改服务器参数语句

ALTER SYSTEM被用来在整个数据库集簇范围内更改服务器配置参数。它比传统的手动编辑kingbase.conf文件的方法更方便。ALTER SYSTEM会把给出的参数设置写入到kingbase.auto.conf文件中,该文件会随着kingbase.conf一起被读入。把一个参数设置为 DEFAULT或者使用RESET变体可以把该配置项从kingbase.auto.conf文件中移除。使用 RESET ALL可以移除所有这类配置项。只有超级用户能够使用ALTER SYSTEM。由于这个命令直接作用于文件系统并且不能被回滚,不允许在一个事务块或者函数中使用它。

例如,设置wal_level:

ALTER SYSTEM SET wal_level = replica;

1.2.2.8. 嵌入式的 SQL 语句

嵌入式的 SQL 语句将 DDL、 DML 和事务控制语句混入过程化语言程序中。嵌入式的 SQL 是一种在您的过程化语言应用程序中使用SQL 的方法。另一种方法是使用一个程序 API,如开放式数据库连接 (ODBC)或 Java 数据库连接 (JDBC) 。

嵌入式的 SQL 语句可以执行以下任务:

  • 定义、 分配、和释放游标(DECLARE CURSOR、OPEN、CLOSE)。

  • 指定一个数据库, 并连接到该数据库(DECLARE DATABASE、CONNECT)。

  • 分配变量名称 (DECLARE STATEMENT)。

  • 初始化描述符(DESCRIB)。

  • 指定如何处理错误和警告(WHENEVER)。

  • 分析并运行 SQL 语句(PREPARE, EXECUTE, EXECUTE IMMEDIATE)。

  • 从数据库中检索数据(FETCH)。

1.3. 优化器概述

数据库使用优化器来优化 SQL 语句,尝试为 SQL 语句产生最优的执行计划。

1.3.1. 优化器的使用

优化器生成执行计划来描述执行方法和步骤。优化器通过考虑几个信息来源来确定哪种执行计划是最有效的。例如,优化器考虑查询条件、可用的访问路径、 系统收集的统计信息、 以及SQL语句中的HINT等。

要执行一个DML语句,可以选择的方法通常是多样的,比如单表扫描可以用全表扫描或者索引扫描;两表连接的方式可以用嵌套连接/哈希连接/排序合并连接;多表的连接顺序也可以是不同的,这些不同的方法都是可以返回DML语句的相同结果的,但是不同方法的效率是不同的,而优化器负责选出一个效率最高的方法,也就是最优执行计划。

在确定SQL语句的最佳执行计划时,优化器将执行以下操作:

  • 逻辑优化:基于规则做等价的语句转换,例如子查询提升/条件化简/Group By键值消除等

  • 物理优化:做代价估算/路径选择等操作,选出一个代价最低的执行路径

  • 根据代价最低的执行路径,生成最优的执行计划

优化器生成处理一个查询的几乎所有可能的方法,并给生成的执行计划中的每个步骤估算一个代价,最低代价的计划被选择为要执行的查询计划。

1.3.2. 优化器的组成

优化器包含两个主要阶段:逻辑优化和物理优化。优化器的输入是一个已解析的查询树,输出是查询的执行计划。这两个阶段的主要作用:

  1. 逻辑优化是基于规则的优化(Rule Based Optimization),它通过找出SQL语句的等价变换形式,使得SQL的执行更为高效。

  2. 物理优化是基于代价的优化(Cost Based Optimization),它通过代价计算,选出代价最低的路径

1.3.2.1. 逻辑优化

逻辑优化是建立在关系代数基础上的优化,通过对关系代数表达式进行逻辑上的等价变化,可能会获得执行性能更好的等式,从而达到提高查询性能的目的,优化器在逻辑优化阶段的主要任务,是根据关系代数的等价变换规则找出更高效的变换形式。例如子查询提升/内联化通用表达式/UNION ALL集合的展平等操作。

1.3.2.2. 物理优化

物理路径指示优化器以何种方式实现逻辑操作,同一个逻辑操作可以有多种物理实现方式,如对表a的扫描可以有全表扫描,索引扫描等,物理优化基于代价计算选择最优的路径。

代价计算会生成三种类型的数据:

  • 选择率

这项数据表示基于某个条件筛选出的数据占总数据集的比例。比如 name 列 的选择率依赖某个查询条件,比如 name=‘张三’。

  • 基数

这项数据表示估算结果集的行数。

  • 代价

这项数据表示执行该路径所需要的资源大小。查询优化器会使用磁盘 I/O、CPU 使用率、和内存使用情况作为因子来参与代价计算。 如果统计信息可用,则做代价计算时使用它们来计算上述数据。统计信息可以提高测量的精确程度。

1.3.3. 访问路径

访问路径是查询中用来检索行的技术。例如,使用索引的查询与不使用索引的查询具有不同的访问路径。 通常,索引访问路径最适合检索表行中的一小部分子集语句, 而完全扫描则对访问表中的大部分表更有效。

数据库可以使用几个不同的访问路径从表中检索数据,如下所示:

  • 全表扫描

这种类型的扫描从一个表读取所有行,并滤掉那些不符合选择条件的行。数据库顺序扫描所有数据块。

  • 索引扫描

索引扫描在索引中搜索SQL 语句访问的索引列值。如果该语句仅访问已被索引的列,则数据库直接从索引读取索引的列值。

优化器对访问路径的选择,基于语句的所有可用的访问路径,和使用每个访问路径或其组合的估算代价。

1.3.4. 优化器统计

优化器统计信息是描述有关数据库和数据库中的对象的详细信息的数据集合。统计准确描述数据存储和分布,优化器用它们来做代价估算从而评估访问路径的效率。 优化器统计信息包括:

  • 表统计

这包括行数、块数、和平均行长等。

  • 列统计

这包括非重复值数目、空值数目、和数据的分布。

  • 索引统计

这包括叶块数目和索引类型。

KingbaseES优化器依赖于表的统计信息来为查询生成最佳执行计划。这些统计信息由 ANALYZE 命令收集,它除了直接被调用之外还可以作为VACUUM命令的一个可选步骤被调用。拥有准确的统计信息很重要,否则缺少统计信息会导致代价估算不准从而产生较差的执行计划,而较差的执行计划可能会降低数据库的性能。

自动清理守护进程如果被启用,当一个表的内容变化很多时,它将自动发出ANALYZE命令。不过,管理员可能更喜欢依靠手动的ANALYZE操作,特别是如果知道一个表的更新不会影响应用程序使用的列的统计信息。守护进程严格地按照一个被插入或更新行数的函数来计划ANALYZE,但它无法判断每次更新统计信息对应用业务是否都有意义。

1.3.5. hint

hint是 SQL 语句中的注释,作为给优化器的一个指示。有时应用程序的设计者比优化器更了解一个特定的应用程序的数据的详细信息,他可以选择一个运行 SQL 语句的更有效方法。应用程序设计者可以在 SQL 语句中使用hint,来指定该语句应该如何运行。在KingbaseES数据库启用hint支持,需要在配置文件中设置 enable_hint = on。

通过示例来说明hint使用,如下面的所示,查询ORDERS表时没使用hint时的执行计划:

explain analyze select * from ORDERS where ORDERID=10250;QUERY PLAN                                                                                                        |
------------------------------------------------------------------------------------------------------------------|
Index Scan using pk_orders on orders  (cost=0.15..8.17 rows=1 width=40) (actual time=0.017..0.018 rows=1 loops=1) |Index Cond: (orderid = 10250)                                                                                   |
Planning Time: 0.084 ms                                                                                           |
Execution Time: 0.039 ms                                                                                          |

通过上面执行计划可以看到,优化器默认使用的是索引扫描index scan。但我们知道ORDERID为10250的数据行位于前几行,所以想强制使用顺序扫描,就可以启用hint将指令传递给优化器,如下所示:

explain analyze select/*+SEQSCAN(ORDERS)*/ * from ORDERS where ORDERID=10250;QUERY PLAN                                                                                      |
------------------------------------------------------------------------------------------------|
Seq Scan on orders  (cost=0.00..24.88 rows=1 width=0) (actual time=0.019..0.020 rows=1 loops=1) |Filter: (orderid = 10250)                                                                     |Rows Removed by Filter: 4                                                                     |
Planning Time: 0.157 ms                                                                         |
Execution Time: 0.039 ms                                                                        |

1.4. SQL处理概述

本节说明了数据库处理创建对象的 DDL 语句、修改数据的 DML 语句、和检索数据的查询语句等的处理方式。

1.4.1. SQL处理的阶段

SQL 处理的步骤分为解析、优化和执行。数据库可能会忽略某些步骤,这取决于具体的语句。

1.4.1.1. SQL解析

SQL 处理的第一阶段是解析。这一阶段涉及将 SQL 语句的各个部分分离为可由其他例程处理的数据结构。 当应用程序发出 SQL 语句时,该应用程序向数据库发出一个解析调用,以准备执行该语句。解析调用会打开或创建一个游标, 它是一个对特定于会话的私有 SQL 区的句柄,其中包含了已分析的 SQL 语句和其他处理信息。 在解析调用期间, 数据库会执行以下检查:

  • 语法检查

  • 语义检查

前面的检查确定在语句执行之前可以发现的错误。但一些错误不能通过解析来捕获。例如,数据库在数据转换过程中可能会遇到死锁或错误,但这仅在语句执行中才会发生。

1.4.1.2. SQL优化

查询优化是选择执行 SQL 语句的最有效手段的过程。数据库对查询的优化基于对正在访问的实际数据收集的统计信息。优化器使用行数、数据集大小、和其他因素,来生成各种可能的执行计划,并为每个计划做代价估算。数据库会使用具有最低代价的计划。数据库对每个唯一的 DML 语句必须至少执行一次解析,并在解析期间执行优化。 DDL 永远不会被优化,除非它包括需要优化的 DML 组件,如子查询。

1.4.1.3. SQL执行

SQL 执行器执行由优化器生成的执行计划,执行计划是一个树状结构,因此执行器递归的处理每一个计划节点来提取它所需要的行结果集,执行器本质上是按请求执行的管道机制,即从顶层节点(根节点)每次向其子节点发出一个获取元素的请求,其子节点收到该请求后递归的向它自己的子节点发出请求,而最终的叶子节点 收到该请求后,会去真正读取表数据,然后每次向上层节点返回一行或多行数据。

举例说明:

explain select * from t1 order by name;QUERY PLAN                                                      |
----------------------------------------------------------------|
Sort  (cost=1181.12..1216.12 rows=14000 width=11)               |Sort Key: name                                                |->  Seq Scan on t1  (cost=0.00..217.00 rows=14000 width=11) |

例子中的顶层节点为Sort,它向其子节点(SeqScan节点)发出要数据的请求,其子节点为叶子节点,收到请求后去读t1的数据表中的数据,每次获取一行数据后向上层返回,Sort节点在获取到所有的t1的数据后,进行排序操作,最终将排序后的结果发送给客户端。

在执行期间,如果数据不在内存中,则数据库将数据从磁盘读入内存。数据库还会取出确保数据完整性所需的所有锁,并记录SQL执行期间所做的任何更改。

1.4.2. DML和DDL处理之间的区别

KingbaseES 数据库对 DDL 的处理不同于 DML。例如,在创建表时,数据库并不会优化 CREATE TABLE 语句。相反,数据库只是解析该 DDL 语句并执行该命令。 与 DDL 不同,大多数 DML 语句都有查询组件,在查询中,游标的执行将查询生成的行放置到结果集中。 数据库可以一次获取一行或分组的结果集行。在 fetch 中,数据库选择行,如果查询请求,则对行进行排序。每次后续获取都将检索结果的另一行,直到获取最后一行为止。

2. PLSQL

本章包括以下主题:

  • 服务器端编程简介

  • PL/SQL概述

  • PL/SQL包

  • 触发器概述

2.1. 服务器端编程简介

在 SQL 之类的非过程化语言中,指定的是要操作的数据集, 而不是要执行什么操作或该操作应如何执行。

在过程化语言程序中,大多数语句的执行取决于其前面或后面的语句及控制结构,如循环或条件分支,而在 SQL 中是没有的。

通过示例来解释过程化语言与非过程化语言之间的区别,假设使用SQL 语句查询ORDERS表,SELECT语句只是请求数据,但并不会在数据上应用程序。但是,假设您希望应用程序能够分析订单表的数据,来计算产品销售量,分析某一段时间每个员工的销售情况,来计算员工的奖金。并将结果生成一份绩效表。这就需要使用条件逻辑和程序流控制的过程化数据库开发程序,可以使用的开发方法如下所示:

  • 使用客户端编程, 将 SQL 语句嵌入到由过程化语言如 C、C++、或 Java 等编写的应用程序中

可以将 SQL 语句置入到源代码中,并在编译之前将其提交给预编译器或 Java 翻译器。或者,您可以消除预编译步骤,使用如 Java 数据库连接 (JDBC) 或 Oracle 调用接口 (OCI) 这样的 API , 使应用程序能够与数据库进行交互。

  • 使用服务器端编程,开发可以直接在数据库使用的程序

应用程序可以显式地调用以 PL/SQL。您还可以创建一个触发器,它是一个存储在数据库中的命名程序单元,在响应指定的事件时调用。

服务器端编程的主要好处,内置于数据库的功能可以在任意位置部署。由数据库而不是由应用程序确定在给定的操作系统上执行任务的最佳方式。此外,通过在服务器上集中应用程序处理,子程序增加可伸缩性,使客户端能够重用代码。由于子程序调用快速而高效,仅仅一个调用就可以启动一个计算密集型的存储子程序,减少了网络流量。 在 KingbaseES 数据库中可以使用PLSQL语言,PL/SQL 是数据库针对 SQL 的过程化扩展。PL/SQL 与数据库集成,支持所有KingbaseES SQL 语句、函数、和数据类型。由数据库 API 编写的应用程序,可以调用 PL/SQL 存储子程序,或发送 PL/SQL 代码块到数据库以被执行。

2.2. PL/SQL概述

PL/SQL 提供了一种服务器端存储的过程化语言,它易于使用并与 SQL无缝集成,而且可移植。您可以使用PL/SQL程序单元的过程化模式对象,来访问和操作数据库数据。 PL/SQL 程序单位一般分为如下几类:

  • PL/SQL 子程序,它存储在数据库中,可以通过应用程序按名称调用。当你创建一个子程序时,数据库解析该子程序,并将其已解析的表示形式存储在数据库中。您可以将一个子程序声明为一个过程或函数。

  • PL/SQL 匿名块,它出现在您的应用程序中,没有名字,也不存储在数据库中。在很多的应用程序中,PL/SQL 块可以出现在任何 SQL 语句可以出现的地方。

KingbaseES 数据库中嵌入了 PL/SQL 编译器和解释器,给与开发人员一个在客户端和服务器上一致和有效的开发模式。此外,PL/SQL 存储过程可从多种数据库客户端调用,比如 Pro*C、JDBC和ODBC等等。

2.2.1. PL/SQL 子程序

PL/SQL 子程序是一个命名的 PL/SQL 块,允许调用方提供参数(可以是输入参数、输出参数、或输入输出参数值)。 子程序解决某一具体问题,或执行相关的任务,并作为模块化的、可维护的数据库应用程序的构造块。子程序是一个过程或函数。过程和函数基本相同,区别在于函数始终向调用者返回单个值,而过程不返回任何值。在本节中的过程一词,可能代表过程或函数。

2.2.2. PL/SQL 子程序的优点

服务器端编程相对于客户端编程有很多的优点,如下所示:

  • 提高性能

相比发出一个个SQL 语句,或将整个 PL/SQL 块的文本发送到数据库中,应用程序必须通过网络发送的信息的量是很小的,因为信息只发送一次,并随后在使用时才调用它。 已编译形式的过程在数据库中是随时可用的,所以在执行时不需要编译。如果该过程已缓存池中,则数据库不需要从磁盘检索它,就可以立即开始执行。

  • 内存分配

因为存储过程利用了数据库的共享内存功能,由对多个用户执行的同一过程,数据库只须将该过程加载一次到内存中。 在多个用户间共享代码,使应用程序对数据库内存的要求大幅减少。

  • 提高生产率

过程增加了开发生产率。通过围绕一组通用的过程来设计应用程序,可以避免冗余编码。 例如,您可以编写过程,来批量处理表中的数据行。任何应用程序可以调用这些过程,而无需重写 SQL 语句。如果数据管理方法改变了,则只须修改过程, 而不必修改使用过程的应用程序。过程也许是实现代码重用的最好方式。因为连接到数据库的任何客户端应用程序,无论它是用何种语言编写的,都可以调用过程,过程提供了在所有环境中最大的代码重用。

  • 完整性

存储过程能改进您的应用程序完整性和一致性。通过围绕一组公用的过程开发应用程序,您可以减少编码错误的可能性。例如,您可以测试一个子程序,来保证它将返回一个准确的结果,验证后,可以在任意数量的应用程序中重用它,而无需重新测试。如果该过程所引用的数据结构改变了,则只须重新编译该过程。调用该过程的应用程序不需要修改。

  • 安全性

存储过程有助于强制执行数据安全。定义者权限过程按其所有者的权限来执行,而不是按当前用户的权限。因此,您可以通过让用户只通过按定义者权限运行的过程和函数来访问数据,以限制用户执行的数据库操作。例如,您可以只授予用户访问更新表的过程的权限,而不授予其访问表本身的权限。当用户调用该过程时,它按其所有者的权限运行。只有权运行该过程的用户可以调用该过程,但不能以除此之外的任何其他方式操作表数据。

2.2.3. PL/SQL 子程序的创建

独立存储的子程序是在模式级别使用 CREATE PROCEDURE 或 CREATE FUNCTION 语句创建的一个子程序。在一个包中定义的子程序称为包子程序,并作为包的一部分。 数据库将子程序作为模式对象存储在数据字典中。每个子程序有一个规范,包括一些参数说明和一个程序体。

示例1:创建存储过程

创建独立 PL/SQL 过程P_INSERT_ORDERS。该过程向ORDERS表中插入数据行:

CREATE SEQUENCE ORDERS_ORDERID_SEQINCREMENT BY 1MINVALUE 1MAXVALUE 9999999START WITH 1NOCACHENOCYCLE;CREATE TABLE ORDERS(ORDERID INT4 CONSTRAINT PK_ORDERS PRIMARY KEY,CUSTOMERID VARCHAR(10) NOT NULL,EMPLOYEEID INT4,ORDERDATE DATE);CREATE PROCEDURE P_INSERT_ORDERS(P_CUSTOMERID VARCHAR(5))ASBEGININSERT INTO ORDERS(ORDERID,CUSTOMERID,ORDERDATE) VALUES(NEXTVAL('ORDERS_ORDERID_SEQ'),'KINGBASE',SYSDATE);END;

2.2.4. PL/SQL 子程序的执行

用户可以以多种方式交互式地执行子程序,如下所示:

  • 使用KingbaseES交互式工具, 如KSQL或KingbaseES数据库对象管理工具

  • 在一个数据库应用程序代码中显式调用它。

  • 在另一个PL/SQL过程代码中显式调用它

有权限的用户可以通过KSQL或KingbaseES数据库对象管理工具执行示例3-2-1创建的P_INSERT_ORDERS过程,向ORDERS表插入一行数据:

CALL P_INSERT_ORDERS ('RDJC');

存储过程依赖于在其主体中引用的对象。数据库自动跟踪和管理这些依赖。例如,P_INSERT_ORDERS过程引用了ORDERS表, 如果您更改了此表的定义且影响到该过程,则该过程必须重新编译以验证它仍然工作正常。通常,数据库自动管理这种依赖关系。

2.3. PL/SQL包

PL/SQL 包是一组相关子程序, 与其使用的游标和变量一起, 作为一个单元存储在数据库中。打包的子程序可以由应用程序或用户显式调用。Kingbase数据库提供了一些内置包,开发应用程序时可以直接使用Kingbase内置包中的过程与函数,既可以 简化应用开发的复杂性,又能提高程序的运行性能。

2.3.1. PL/SQL包的优点

PL/SQL包为应用程序开发人员提供了许多好处,其优点如下:

  • 模块化

通过使用包可以把逻辑上相关的变量、函数等封装成为一个 PL/SQL 模块。每个包都易于理解,包与包之间的接口也简单明了,定义也很方便,这样非常有利于应用开发。

  • 应用程序设计简单

当设计一个应用程序时,最初需要的是包头的接口信息。可以先编写包规范代码并编译,而不需要定义包体;包体可以直到需要完成应用程序时再定义。

  • 功能增强

包中变量和游标在一个会话中会一直存在,可以被当前会话中的包函数和包存储过程共享,可以在普通的存储过程和函数中使用包中全局的变量、游标、包的存储过程和包的函数。可以在整个事务中保持对数据的访问,而不必存储在数据库中。

  • 高效性

第一次调用包函数或包存储过程时,整个包被加载到内存,以后再访问该包的对象时,不需要再进行I/O操作。对包的授权同时将包中所有的对象授权。

2.3.2. PL/SQL 包的创建

分两个部分创建包:包头和包体。包头声明包的所有过程结构,而包体定义包的所有过程结构。

示例2:创建包

如下所示,创建PKG_ORDERS包头的语句的一部分,封装了用于管理订单表的几个子程序。包的每个部分用不同的语句创建。

CREATE TABLE ORDERS
(ORDERID INT4 CONSTRAINT PK_ORDERS PRIMARY KEY,CUSTOMERID VARCHAR(10) NOT NULL,EMPLOYEEID INT4,ORDERDATE DATE
);CREATE PACKAGE PKG_ORDERS ASPROCEDURE P_INSERT_ORDERS (P_CUSTOMERID VARCHAR(5));PROCEDURE P_ORDERS_CUSTOMERS_QRY(P_ORDERID INT,P_CUSTOMERID VARCHAR(5));FUNCTION F_ORDER_DETAILS_EXTENDED (F_ORDERID INT,F_PRODUCTID INT) RETURN NUMBER;FUNCTION F_ORDER_SUBTOTALS(F_ORDERID INT,F_DATE_FROM DATE,F_DATE_TO DATE)RETURN NUMBER;
END PKG_ORDERS;

这个包头一共定义了四个过程和函数,对这个包有权限的用户都可以调用包中这些过程对象。 CREATE PACKAGE BODY 命令定义在规范中声明的过程对象。包体必须在和包头相同的模式中创建。在创建包之后,您就可以开发应用程序,并在其中调用这些公共过程或函数,或抛出包中的任何公共例外。

2.3.3. PL/SQL 包的执行

您可以从过程、应用程序和KingbaseES工具引用包内容。数据库应用程序在必要时显式调用包内的过程。在取得对包的授权后,用户可以显式运行其中的任何过程。 例如,可以使用KSQL连接数据库,然后运行示例2中包PKG_ORDERS的存储过程:

CALL PKG_ORDER.P_INSERT_ORDERS ('RDJC');

2.3.4. PL/SQL 匿名块

匿名块是一个未命名的、 非持久化的 PL/SQL 单元。匿名块的典型用途包括:

  • 启动调用子程序和包结构元素

  • 隔离异常处理

  • 通过在其他 PL/SQL 块中嵌套代码来管理控制

匿名块没有存储子程序的代码重用优势。下表总结了这两类程序单元的之间的差异。

功能

匿名块

子程序

是否指定了一个名字

是否每次使用时都要重新编译

是否存储在数据库中

是否可由其它应用程序调用

是否能返回绑定变量值

是否能返回函数值

是否能接受参数

匿名块包括一个可选的声明性部分、 一个可执行部分、 和一个或多个可选的异常处理程序。

示例3: 创建匿名块

查询ORDERS表的总行数,储存到一个变量中,并打印:

CREATE TABLE ORDERS
(ORDERID INT4 CONSTRAINT PK_ORDERS PRIMARY KEY,CUSTOMERID VARCHAR(10) NOT NULL,EMPLOYEEID INT4,ORDERDATE DATE
);
INSERT INTO ORDERS(ORDERID,CUSTOMERID,ORDERDATE) VALUES(100,'KINGBASE','2000-01-01');
INSERT INTO ORDERS(ORDERID,CUSTOMERID,ORDERDATE) VALUES(102,'KINGBASE','2000-03-01');DECLAREV_COUNT INT;
BEGINSELECT COUNT(*) INTO V_COUNT FROM ORDERS;RAISE NOTICE '%',V_COUNT;
END;

KingbaseES数据库编译PL/SQL匿名块,并将其放在缓存池中,但它不会在数据库中存储其源代码或已编译版本,不能在当前运行实例之外能重复使用。与过程不同的是,一个匿名块在它每次加载到内存中都要被重新编译。

2.3.5. PL/SQL 语言结构

PL/SQL 块可以包括各种不同的 PL/SQL 语言结构。这些结构包括如下:

  • 变量和常量

您可以在过程、函数、或包内声明这些结构。在你需要在 SQL 或 PL/SQL 语句中捕获或提供一个值时,您可以使用变量或常量。

  • 游标

您可以在过程、函数、或包中显式声明一个游标,以便对KingbaseES数据库数据进行记录行的处理。 PL/SQL也可以隐式声明游标。

  • 异常

PL/SQL 允许您显式处理异常,即在 PL/SQL 代码的处理过程中抛出的内部的或用户定义的错误。

PL/SQL可以运行动态SQL语句,动态SQL句被存储为字符串,可以是手工输入的或在运行时由其程序生成。这种技术使您能够创建通用过程。例如,您可以创建一个过程,用于操作一个直到运行时才知道其名称的表。

2.3.6. PL/SQL 集合和记录

许多编程技术都使用集合类型,如数组、列表、嵌套表、集合等。为在数据库应用程序中支持这些技术,KingbaseES数据库提供了集合和记录数据类型。

2.3.6.1. 集合

集合是一组有序的、具有相同类型的元素。KingbaseES数据库提供了 TABLE 和 VARRAY 数据类型,使您能够声明关联数组(Associative Array)、嵌套表(Nested Table)和可变数组(Varray)。 每个元素都有一个唯一的下标,以确定其在该集合中的位置。若要创建一个集合,你得首先定义一个集合类型,然后声明一个该类型的变量。 集合的工作原理与第三代编程语言中的数组类似。此外,集合可以作为参数传递。所以,你可以使用他们在数据库中的表、客户端应用程序、和存储子程序等之间,移入或移出数据列。

2.3.6.2. 记录

记录(RECORD)是一种复合变量,可以存储不同类型的的数据值,类似于 C、C++、或 Java 中的结构类型。记录可用于容纳来自多个表行,或多个表行中的某些列的数据。 这些项的类型不同,但逻辑上相关。记录为每个项都包含了一个字段,让你可以视其为一个逻辑单元。 您可以使用 %ROWTYPE或者%TYPE 属性来声明一条记录,以表示一个表行或从游标读取的行。

2.3.7. PL/SQL的运行

PL/SQL 支持解释执行。解释执行是将源代码逐条转换成目标代码,在运行时解释一条,执行一条的过程。 PL/SQL单元存储在数据库中。当应用程序调用存储过程时,数据库会将已编译的程序单元加载到系统缓存区中。PL/SQL解释器和 SQL 语句执行器共同处理过程中的语句。

2.4. 触发器概述

数据库触发器是一个已编译的存储程序单元,使用 PL/SQL编写,数据库在某些情况下会自动调用。每当发生下列操作之一时,触发器就会触发:

  1. 由任何用户在一个特定的表或视图上,发出 DML 语句

DML 语句修改模式对象中的数据。例如,插入和删除行即是 DML 操作。

  1. 由任何用户或特定用户发出 DDL 语句

DDL 语句定义模式对象。例如,创建表并添加一列即是 DDL 操作。

  1. 数据库事件

用户登录或注销、错误、和数据库启动或关闭,是触发器可以调用的事件。

触发器是模式对象,类似于子程序;但其调用方法不同。子程序由用户、应用程序、或触发器显式运行。而触发器是在触发的事件发生时由数据库隐式调用的。

2.4.1. 触发器的优势

正确使用触发器使您能够更高效的使用数据库应用程序。您可以使用触发器执行以下任务:

  • 自动生成派生列中的值

  • 阻止无效事务

  • 提供审计和事件日志记录

  • 记录有关访问表的信息

您可以使用触发器强制执行对所有客户端应用程序都适用的底层业务规则。例如,几个应用程序都可能要访问ORDERS表。如果此表上的某个触发器可以确保插入数据的格式,则不需要在每个客户端中重复这种业务逻辑。因为该触发器不能被应用程序绕过,触发器中的业务逻辑会被自动应用。

您可以使用触发器或完整性约束,来定义和执行任何类型的完整性规则。但是,当不能使用一个完整性约束来定义业务规则时,可以使用触发器来强制执行这种复杂的业务规则。 但过度使用触发器,可能导致复杂的相互依赖关系,在一个大的应用程序中可能很难维护。当调用触发器时,在其触发器操作中的 SQL 语句可能会触发其他触发器,导致级联触发,可能会产生意想不到的结果。

2.4.2. 触发器类型

触发器可以根据其触发方式和他们所执行的操作类型进行分类。KingbaseES数据库支持以下类型的触发器:

  • 行级触发器

行触发器在表每次受到触发语句影响时触发。如果触发语句未影响任何行,则行触发器不会运行。

  • 语句级触发器

语句触发器针对触发语句只触发一次,无论触发语句影响的行数。

  • INSTEAD OF 触发器

数据库会触发 INSTEAD OF 触发器,而不是执行触发语句。这些触发器可用于透明地修改不能直接通过 DML 语句修改的视图。

  • 事件触发器

KingbaseES中的事件触发器对数据库来说是全局的,并且可以捕捉DDL事件。可以用任何事件触发器支持的过程语言编写事件触发。只要一个与事件触发器相关的事件在事件触发器所在的数据库中发生,该事件触发器就会被触发。事件触发器可分为以下几类:

  • 系统事件触发器可以由如数据库实例启动和关闭或错误消息之类的事件引起。

  • 用户事件触发器会因为与用户登录和注销、DDL 语句、和 DML 语句等相关的事件而激发。

2.4.3. 触发时间

您可以定义触发时间来决定触发器操作是要在触发语句之前运行,还是之后运行。可以选择如下的触发时间:

  • 触发语句之前

  • 在受触发语句影响的每行之前

  • 在受触发语句影响的每行之后

  • 触发语句之后

对语句级和行级触发器,BEFORE 触发器可以增强安全性,并在对数据库进行更改之前启用业务规则。而 AFTER 触发器则对日志记录操作很有用。 复杂触发器可以在多个时间点触发。复杂触发器提供一种编程方法,使你可以在多个不同的时间点,对共享的数据实施操作。

2.4.4. 触发器的创建

使用 CREATE TRIGGER 语句创建或替换数据库触发器。PL/SQL 触发器有以下基本组件:

  • 触发器名称

在相同的模式中,触发器的名称必须是唯一的。

  • 触发事件或语句

触发事件或语句是导致触发器被调用的 SQL 语句、数据库事件、或用户事件

  • 触发器时间

触发程序的动作时间,可以是BEFORE、AFTER 或 INSTEAD OF。

  • 触发的操作

触发的操作是包含 SQL 语句和代码的过程,当发出一个触发语句、且触发器限制的计算结果为 true 时将被运行。

示例4:一个PLSQL触发器函数

这个例子的触发器实现以下功能:任何时候一个行在表中被插入或更新时,当前用户名和时间也会被标记在该行中。并且它会检查给出了一个雇员的姓名以及薪水是一个正值。

--创建表
CREATE TABLE EMP(EMPNAME TEXT,SALARY INTEGER,LAST_DATE TIMESTAMP,LAST_USER TEXT
);--创建函数
CREATE FUNCTION EMP_STAMP() RETURNS TRIGGER AS $EMP_STAMP$
BEGIN-- 检查给出了 EMPNAME 以及 SALARYIF NEW.EMPNAME IS NULL THENRAISE EXCEPTION 'EMPNAME CANNOT BE NULL';END IF;IF NEW.SALARY IS NULL THENRAISE EXCEPTION '% CANNOT HAVE NULL SALARY', NEW.EMPNAME;END IF;-- 检查工资小于0的异常情况IF NEW.SALARY < 0 THENRAISE EXCEPTION '% CANNOT HAVE A NEGATIVE SALARY', NEW.EMPNAME;END IF;-- 记录工资单的变化NEW.LAST_DATE := CURRENT_TIMESTAMP;NEW.LAST_USER := CURRENT_USER;RETURN NEW;
END;
$EMP_STAMP$ LANGUAGE PLSQL;--创建触发器
CREATE TRIGGER EMP_STAMP BEFORE INSERT OR UPDATE ON EMPFOR EACH ROW EXECUTE FUNCTION EMP_STAMP();

2.4.5. 触发器的内部执行

KingbaseES数据库在内部使用与执行子程序相同的步骤来执行触发器。唯一的细微区别在于,如果用户有权运行触发语句,则他有权触发该触发器。除了这个区别之外,数据库使用与存储子程序相同的方式来验证和运行触发器。

2.4.6. 触发器的存储

与 PL/SQL 存储过程类似,KingbaseES数据库将触发器以已编译形式存储在数据库模式中。当 CREATE TRIGGER 语句提交后,其编译后的 PL/SQL 代码被存储在数据库中,并重新加载到内存中。

KingbaseES数据库概念(二)--数据访问相关推荐

  1. 金仓数据库KingbaseES数据库概念(四)--事务

    目录 1. 事务的概念 2. 事务的特性 3. 数据库对事务的管理 4. 并发控制 4.1. 事务隔离 4.2. 显式锁定 同大多数的商业数据库一样,KingbaseES数据库也引入了事务的概念.本章 ...

  2. KingbaseES数据库概念(一)--数据库简介

    1. 金仓数据库的发展历史 KingbaseES数据库是人大金仓自主研发的一种通用关系型数据库,产品融合了人大金仓在数据库领域几十年的产品研发和企业级应用经验,可满足各行业用户多种场景的数据处理需求. ...

  3. VB.NET学习笔记:ADO.NET操作ACCESS数据库——ADO.NET数据访问接口

    一.ADO.NET概述 Ado.net基于XML和离线计算模型. ADO.net的两个核心组件:.Net数据提供程序.DataSet. .net数据提供程序用来与数据库的连接,如SQLServer.n ...

  4. .Net+MySQL组合开发(二) 数据访问篇

    一.建立数据库.表.添加数据 这里我们使用图形化操作的SQL Manager 2005 Lite for MySQL来建立数据,它的操作界面非常类似OFFICE软件,使用方便.很容量上手.下面开始建立 ...

  5. MySQL数据库实验二 数据基本查询

    ★观前提示:本篇内容为mysql数据库实验,代码内容经测试过,可能一小部分有所疏漏,也有会不符合每个人实验的要求的地方,因此以下内容建议仅做思路参考,. 一.实验目的 1.掌握SQL查询语句的一般格式 ...

  6. 不同数据库间的数据访问--dblink

    在我们实际应用过程中会经常遇到这个问题,两个不同系统间要进行数据传输. 那我现在的这个项目来说吧,我这里的基础数据是来自其他系统,这个时候我们就需要读取其他数据库表中的数据了. 遇到这个问题创建dbl ...

  7. 数据库——实验二 数据查询

    1.实验目的 理解SQL 程序设计基本规范,熟练运用SQL 语言实现数据查询,包括单表查询.分组统计查询和连接查询.嵌套查询合和集合查询. 2.实验内容和要求 针对tpch 数据库或自建数据库test ...

  8. mysql查询2个isbn数据,数据库实验二 数据查询

    ALTER TABLE 书目 ADD 出版年份 VARCHAR(100); UPDATE 书目 SET 出版年份='2005' WHERE ISBN='7040195836'; UPDATE 书目 S ...

  9. 数据库-实验二-数据查询

    --查询"红楼梦"目前可借的各图书编号,及所属版本信息 select 图书编号,出版单位 from 书目,图书 where 书目.isbn=图书.isbn  and 书名='红楼梦 ...

最新文章

  1. spring-boot学习资料
  2. Android线程实例讲解
  3. 苹果电脑+VR头显不久将成为现实,macOS新系统正式上线
  4. update语句的返回值是什么
  5. 从零开始学视觉Transformer (10):目标检测DETR-1
  6. 某项目网络实施中的几个关键点解析
  7. java 抽象类 模板_Java学习day21-抽象类(abstract class)和模板设计模式(TemplateMethod)...
  8. SpringBoot2整合Flyway(二)
  9. kux播放器android,kux格式转换工具
  10. 学习笔记|复杂嵌套的三目表达式如何分割?
  11. JVM调优工具的使用方法
  12. 企业遇到什么问题一定要用360评估?
  13. 网易考拉海购Dubbok框架优化详解(学习笔记)
  14. citrix应用程序虚拟化_在Citrix环境中部署和更新Microsoft Access应用程序
  15. sort()函数排序vector
  16. 百度AI使用方案:黑白图片上色
  17. Zynq 【SDK裸机开发之PS】——串口接收缓存
  18. Android 悬浮歌词(迷你歌词)效果解读 (转)
  19. 焊接件技术要求怎么写_不锈钢焊接技术要求怎么写哇?
  20. 支付宝(查询对账单下载地址+文件下载+解压+遍历文件+读文件)

热门文章

  1. linux+wine乱码,Ubuntu下Wine乱码解决方法与中文支持
  2. 2021年T电梯修理考试资料及T电梯修理考试试卷
  3. dagger android,dagger android 学习(二):AndroidInjector的使用
  4. centos挂载U盘失败no valid journal superblock found EXT4-fs (sda): error loading journal
  5. 【应用笔记】AN1088_APM32F4xx系列ETH移植LWIP
  6. P1024 一元三次方程求解 两种方法
  7. Grafana可视化工具-之变量介绍
  8. /u 反斜杠u 编码总结
  9. 如何对jmeter设置IP欺骗
  10. TH2830新型LCR数字电桥报价/技术资料-安泰测试Agitek