1.4 数据库概念

1.4.1 结构化查询语言

结构化查询语言 (SQL) 是用来查询和处理关系数据库中的数据的语言。

1.4.2 数据操作语言

数据操作语言 (DML) 语句是用来处理数据库数据的高度标准化 SQL 语句。

不管使用什么数据库,DML 语句在本质上是相同的。 Driver for JDBC 基于 DML。 它将以 XDS XML 表示的 Identity Manager 事件映射到标准化的 DML 语句。

以下示例显示了若干个 DML 语句:

SELECT * FROM usr; INSERT INTO usr(lname) VALUES('Doe'); UPDATE usr SET fname = 'John' WHERE idu = 1;

1.4.3 数据定义语言

数据定义语言 (DDL) 语句可处理数据库对象,例如表、索引和用户帐户。

DDL 语句是专有语句,因数据库的不同而有很大的差别。 尽管 Driver for JDBC 基于 DML,仍可以在 XDS 事件中嵌入 DDL 语句。有关其它信息,请参考在 XDS 事件中嵌入 SQL 语句

以下示例显示了若干个 DDL 语句:

CREATE TABLE usr ( idu   INTEGER, fname VARCHAR2(64), lname VARCHAR2(64) );

CREATE USER idm IDENTIFIED BY novell;

NOTE:本指南各个部分使用的示例均适用于 Oracle 数据库。

1.4.4 视图

视图是一种逻辑表。

用户使用 SELECT 语句执行查询时,系统将通过执行定义视图时提供的 SQL 查询建立视图。 视图是有用的提取机制,它可以将任意结构的多个表表示成一个表或逻辑数据库类。

CREATE VIEW view_usr ( pk_idu, fname, lname ) AS SELECT idu, fname, lname from usr;

1.4.5 身份列/顺序

身份列和顺序用于生成唯一的主键值。 Identity Manager 可以关联这些值,并对其执行其它操作。

身份列是一个自行递增的列,用于唯一地标识表中的行。 在表中插入一个行后,系统将自动填写身份列值。

顺序对象是一个计数器,可用于唯一地标识表中的行。 与身份列不同,顺序对象不与单个表联结。 但是,如果单个表使用了顺序对象,则可以使用该对象来获得相同的结果。

下面是顺序对象的一个示例:

CREATE SEQUENCE seq_idu START WITH 1 INCREMENT BY 1 NOMINVALUE NOMAXVALUE ORDER;

1.4.6 事务

事务是由一个或多个语句组成的原子数据库运算。

事务完成后,将提交事务中的所有语句。 如果事务被中断,或事务中的某个语句发生错误,则这种情况称为事务回滚。 事务回滚后,数据库将保持事务开始之前的相同状态。

有两种类型的事务:手动(用户定义)或自动。 手动事务可以包括一个或多个语句,并且必须显式提交。 自动事务包括一个语句,需要在执行每个语句后隐式提交。

手动(用户定义)事务

手动事务通常包含多个语句。 DDL 语句通常不能与手动事务中的 DML 语句分在一组。

以下示例说明手动事务:

SET AUTOCOMMIT OFF INSERT INTO usr(lname) VALUES('Doe'); UPDATE usr SET fname = 'John' WHERE idu = 1; COMMIT; -- explicit commit

自动事务

自动事务只包括一个语句。 它们通常被称为自动提交的语句,因为更改是在每个语句之后隐式提交的。 自动提交的语句与其它任何语句无关。

以下示例说明自动事务:

SET AUTOCOMMIT ON INSERT INTO emp(lname) VALUES('Doe'); -- implicit commit

1.4.7 储存过程或函数

储存过程或函数是储存在数据库中的可编程逻辑。 储存过程或函数几乎可由任何环境调用。

《订购者》通道可以使用储存过程或函数,从插入到表的行中检索主键值以创建关联。 也可以从嵌入的 SQL 语句或触发器内部调用储存过程或函数。

储存过程和函数之间的差别因数据库的不同而异。 一般而言,两者都可以返回输出,但是返回的方式不同。 储存过程通常通过参数返回值。 函数通常通过标量返回值或结果集来返回值。

以下示例说明返回顺序对象下一个值的储存过程定义:

CREATE SEQUENCE seq_idu START WITH 1 INCREMENT BY 1 NOMINVALUE NOMAXVALUE ORDER;
CREATE PROCEDURE sp_idu(		io_idu IN OUT INTEGER) IS BEGIN IF (io_idu IS NULL) THEN SELECT seq_idu.nextval INTO io_idu FROM DUAL; END IF; END sp_idu;

1.4.8 触发器

数据库触发器是与表关联的可编程逻辑,它在特定的条件下执行。 如果符合触发器的执行准则,则认为是触发了触发器。

通常,可以使用触发器在数据库中创建副作用。 在 Driver for JDBC 环境中,可以使用触发器截获事件发布。 下面是 usr 表中的数据库触发器的一个示例。

CREATE TABLE usr ( idu   INTEGER, fname VARCHAR2(64), lname VARCHAR2(64) );
-- t = trigger; i = insert CREATE TRIGGER t_usr_i AFTER INSERT ON usr FOR EACH ROW

BEGIN UPDATE usr SET fname = 'John'; END;

针对带有触发器的表执行语句时,如果语句满足触发器中指定的条件,则会触发触发器。 以上表为例,假设执行以下插入语句:

INSERT INTO usr(lname) VALUES('Doe')

执行该插入语句后,将触发触发器 t_emp_i,同时还将执行以下更新语句:

UPDATE usr SET fname = 'John'

触发器通常可以在触发它的语句之前或之后触发。 作为数据库触发器一部分执行的语句通常包含在与触发器语句相同的事务中。 在上例中,INSERTUPDATE 语句将被一起提交或回滚。

1.4.9 Instead of 触发器

Instead of 触发器是与视图关联的可编程逻辑,它在特定的条件下执行。

可以使用 Instead of 触发器使视图变得可写或可订购。 它们通常用于定义在视图中执行 INSERTUPDATEDELETE 时的具体情况。 下面是 usr 表中 Instead of 触发器的一个示例。

CREATE TABLE usr ( idu   INTEGER, fname VARCHAR2(64), lname VARCHAR2(64) );

CREATE VIEW view_usr ( pk_idu, fname, lname ) AS SELECT idu, fname, lname from usr; -- t = trigger; i = insert CREATE TRIGGER t_view_usr_i INSTEAD OF INSERT ON usr BEGIN INSERT INTO usr(idu, fname, lname) VALUES(:NEW.pk_idu, :NEW.fname, :NEW.lname); END;

针对带有 Instead of 触发器的视图执行语句时,如果该语句满足触发器中指定的条件,则会执行 Instead of 触发器。 与触发器不同,Instead of 触发器始终在触发语句之前执行。 此外,与常规触发器不同,Instead of 触发器是代替触发语句而不是接在该语句之后执行。

以上述视图为例,假设执行下列插入语句,而不是执行原来的插入语句:

INSERT INTO view_usr(pk_idu, fname, lname) VALUES(1, ‘John', ‘Doe')

Instead of 触发器 t_view_usr_i 不是执行原来的语句,而是触发并执行下列语句:

INSERT INTO usr(idu, fname, lname) VALUES(:NEW.pk_idu, :NEW.fname, :NEW.lname);

在本示例中,这些语句正好等效。