使用 CREATE DATABASE 语句创建新数据库。
该语句是 SQL ANSI/ISO 标准的扩展。
语法
用法
该语句是 ANSI 标准语法的扩展。(SQL 语句的 ANSI/ISO 标准不为数据库的构造,即数据库的形成过程指定任何语法。)
CREATE DATABASE 指定的数据库成为当前的数据库。
如果 DBCREATE_PERMISSION 配置参数没有设置,则任何用户都可创建数据库。然而,如果该配置文件包含一个或多个 DBCREATE_PERMISSION 指定,则只有指定的用户才能创建数据库。无论 DBCREATE_PERMISSION 是否设置,用户 gbasedbt 都可以使用 CREATE DATABASE 语句。
您声明的数据库名称在您正在工作的数据库服务器环境中必须是唯一的。数据库服务器创建描述新数据库的结构的系统目录表。
如果您包含了可选的 IF NOT EXISTS 关键字,则当指定的数据库名称已经存在于您要连接的由数据库服务器实例管理的数据库中时,数据库不会采取任何操作(而不是向应用程序发送异常)。
当创建数据库时,只有您自己可以存取它。它不会让其他用户访问,除非您作为 DBA 通过运行 GRANT 语句授权。
如果先前的 CONNECT 语句建立了到数据库的显式连接,而且该连接仍是当前连接,那么在使用 DISCONNECT 语句关闭该显式连接之前,你不能使用 CREATE DATABASE 语句(或任何创建隐式连接的 SQL 语句)。
在 GBase 8s ESQL/C 中,CREATE DATABASE 语句不能出现在多语句 PREPARE 操作中。
您要连接的数据库服务器实例的 SQL_LOGICAL_CHAR 配置参数记录在该新数据库的系统目录中。SQL_LOGICAL_CHAR 配置参数扩展内置字符数据类型声明中的大小设定的扩展。即使 GBase 8s 实例管理的数据库被新的 SQL_LOGICAL_CHAR 值停止并重启,也不能更改此设置,它会持续到数据库被删除。systables 系统目录表的 flags 列为此数据库编码 SQL_LOGICAL_CHAR 设置。
如果您未指定 dbspace ,则缺省情况下,数据库服务器在 root dbspace 中创建系统目录表。然而,如果您启用数据库自动定位,则缺省情况下,数据库创建于被此服务器选择的 dbspace 中。要启用数据库的自动定位,请将 AUTOLOCATE 配置参数或会话环境变量设置为一个正整数。
以下语句在 root dbspace 或由服务器选定的 dbspace 中(这取决于是否要启用自动定位)创建 vehicles 数据库:
CREATE DATABASE vehicles;
由于以上示例不包含日志记录设定和 NLSCASE 设定,因此缺省情况下
l vehicles 数据库不支持事务日志记录,
l 并且如果它的语言环境使用区分大小写字母的代码集,则数据库对所有的内置的字符数据类型都区分大小写。
以下语句在 research dbspace 中创建 vehicles 数据库:
CREATE DATABASE vehicles IN research;
但是如果没有 DROP DATABASE 语句删除现有的第一个示例创建的 vehicles 数据库,则第二个示例发生错误并失败,并且没有数据库被创建,因为 vehicles 数据库的标识符在数据库服务器实例中不是唯一的。
CREATE DATABASE 语句的日志记录选项决定了为数据库所作的日志记录类型。失败的情况下,数据库服务器使用日志来重新创建您的数据库中的所有已提交的事务。
以下示例使用 WITH LOG 选项创建带有未缓冲日志记录的数据库:
CREATE DATABASE unbufDatabase WITH LOG;
如果不指定 WITH LOG 关键字,则 GBase 8s 将创建不能使用支持事务日志记录的事务或语句(BEGIN WORK 、COMMIT WORK 、ROLLBACK WORK 、RELEASE SAVEPOINT 、ROLLBACK TO SAVEPOINT 、SET IMPLICIT TRANSACTION 、SET LOG 和 SET ISOLATION) 的没有日志记录的数据库。
当您在高可用集群的辅助服务器上创建数据库时,必须使用 WITH LOG 选项。
以下示例创建了使用已缓冲的日志的数据库:
CREATE DATABASE vehicles WITH BUFFERED LOG;
如果使用已缓冲的日志,则会略微提高日志记录的性能,但要冒失败之后无法重新创建最后几个事务的危险。
当在 CREATE DATABASE 语句中使用 LOG MODE ANSI 选项时,您创建的数据库就是兼容 ANSI 的数据库,且符合SQL 语言的 ANSI/ISO 标准。
以下示例创建兼容 ANSI 的数据库:
CREATE DATABASE employees WITH LOG MODE ANSI;
兼容 ANSI 的数据库与不兼容 ANSI 的数据库存在几个方面的不同。包括以下特征的不同:
l 所有 SQL 语句自动包含在事务中。
l 所有数据库使用未缓冲的日志记录。
l 实施所有者命名。
除非您是所有者,否则查看任何表、视图、同义词、索引或约束时必须使用所有者名称。除非您将所有者名称包含在引号中,否则所有者名称中的字母缺省采用大写字符。(要防止在未分隔所有者名称中小写字母升档,您可以将 ANSIOWNER 环境变量设置为 1。)
此外,UDR 的例行签名包含所有者的名称;在不兼容 ANSI 的数据库中,它只对 sysdbopen( ) 和 sysdbclose( ) 程序为真。
l 对于会话,缺省隔离级别为 REPEATABLE READ 。
l 对象上的缺省权限与那些不兼容 ANSI 的数据库不同。当您创建表或同义词时,缺省情况下其它用户不接收对其存取权限(如果是 PUBLIC 组的成员)。
l 所有的 DECIMAL 数据类型时定点值。如果您声明列为 DECIMAL(p),则缺省大小是零,表明只能存储整型值。(在不兼容 ANSI 的数据库中,DECIMAL(p) 是浮点数据类型,它的规模大到足以存储一个值的指数符号。)
兼容与不兼容 ANSI 的数据库之间存在其它小差别。这些差别在此手册中与其它相关 SQL 语句一起记录。
创建兼容 ANSI 的数据库不意味着当您运行数据库时,自动收到 SQL 语法 ANSI/ISO 标准的 GBase 8s 警告。还必须使用 -ansi 标记或 DBANSIWARN 环境变量来接收这类警告。
有关 -ansi 和 DBANSIWARN 的其它信息,请参阅 《GBase 8s SQL 指南:参考》 。
您可以显式地创建区分大小写或不区分大小写的数据库。
缺省情况下,在数据库中的区域设置将代码集的分离子集分类为大写字母和小写字母, GBase 8s 数据库创建为区分大小写。数据库语言环境通过设置 DB_LOCALE 环境变量而定义。语言环境的示例,若其代码集在缺省 US English 语言环境中识别字母大小写,则在升序排列中,小写字母会超过大写字母。在缺省的语言环境中,以下语句创建区分大小写的数据库:
CREATE DATABASE employees IN dbspaceYee WITH BUFFERED LOG;
要显式地创建区分大小写的数据库,请将 NLSCASE SENSITIVE 关键字包含在 CREATE DATABASE 语句中,并作为其最后的指示,如下所示:
CREATE DATABASE stores IN dbsp1 WITH LOG NLSCASE SENSITIVE;
因为缺省启用区分大小写,以下语句具有相同的作用:
CREATE DATABASE stores IN dbsp1 WITH LOG;
在区分大小写的数据库中,例如 Boolean 条件 'M' MATCHES 'm' 计算为假。
所有的 GBase 8s 数据库对于内置 CHAR 、LVARCHAR 和 VARCHAR 数据类型的字符串字符操作都区分大小写。如果您创建区分大小写数据库,则不论缺省或显式使用 NLSCASE SENSITIVE 关键字,如果数据库语言环境支持字母大小写,数据库仍将区域语言支持的数据类型 NCHAR 和 NVARCHAR 看作区分大小写。
创建不区分大小写的数据库
在某些应用程序中,字符串的大小写会被忽略。 例如,数据项处理,可能接受字符串 'M' 和 'm' 在一条记录中是逻辑等价的。对于大数据集,应用条件逻辑将两种情况变量转换为单个值可能导致性能低于将记录存储在不区分大小写的数据库的 NCHAR 或 NVARCHAR 列中,其中 'M' 和 'm' 字符串编码都是不区分大小写的值此处的条件 'M' MATCHES 'm' 对 NCHAR 或 NVARCHAR 列计算为真。
每个创建有 NLSCASE INSENSITIVE 属性的数据库存储大小写的 NCHAR 和 NVARCHAR 字母,正如它们被加载到它们的表中一样;查询返回的任何未更改的记录都具有原始字母。然而,在所有的对 NCHAR 和 NVARCHAR 值的操作(例如:排序、分组或标识重复行)中,数据库服务器会忽略字母大小写的变化,例如:字符串 'Mi' 和 'mI' 的值是一样的。有关字母大小写的信息没有被丢弃,但是当数据库服务器处理 NLS 数据类型时仍不会使用这些信息。
当在 CREATE DATABASE 语句中包含 NLSCASE INSENSITIVE 关键字作为其最后的指定时,数据库服务创建处理以下字符串类型时不考虑字母大小写的数据库:
l 存储在 NLS 数据类型的 NCHAR 和 NVARCHAR 列中字符串
l 存储为基于 NCHAR 或 NVARCHAR 数据类型的 DISTINCT 数据类型的字符串
l 存储为具有集合数据类型的那些数据类型的元素的字符串
l 存储在指定或未指定的 ROW 数据类型中的以上数据类型的字段中字符串
l 存储为 SPL 变量的那些数据类型的字符串
l 隐式或显示强制转型为那些数据类型的字符串
l 作为被函数返回的那些数据类型的输出参数的字符串
此处的 "这些数据类型" 引用了在同一列表中标识的字符数据类型。
以下语句创建了具有 NLSCASE INSENSITIVE 属性的数据库:
CREATE DATABASE stores IN dbsp2 WITH BUFFERED LOG NLSCASE INSENSITIVE;
重要: 创建为 NLSCASE INSENSITIVE 的数据库将所有其它内置字符数据类型(CHAR 、LVARCHAR 和 VARCHAR)都对待为区分大小写。也就是说,如果它们的数据类型不在上表的 NLS 字符数据类型中,则区分大小写的数据库仍可以执行区分大小写字符串值的处理。
要在区分大小写的数据库的 NCHAR 或 NVARCHAR 数据类型的字符串上执行区分大小写操作,您必须显式地将字符串强制转型成 CHAR 、LVARCHAR 或 VARCHAR 数据类型,然后再执行区分大小写操作。
NLSCASE INSENSITIVE 查询的示例
在区分大小写的数据库中,当一个查询调用聚集函数或者对 NCHAR 或 NVARCHAR 列包含 GROUP BY 子句时,数据库服务器将数据库中的大小写字母作为重复的值,程序片段示例如下。
CREATE DATABASE casedb WITH LOG NLSCASE INSENSITIVE;
CREATE TABLE foo (cc CHAR(5), nc NCHAR(5));
INSERT INTO foo VALUES ('GBASE', 'gBASE');
INSERT INTO foo VALUES ('gbase', 'gbaSE');
INSERT INTO foo VALUES ('gbase', 'gbaSE');
INSERT INTO foo VALUES ('GBase', 'GBase');
SELECT COUNT(nc) FROM foo
GROUP BY nc;
SELECT COUNT(nc) FROM foo
WHERE nc = 'gbase' GROUP BY nc;
在以上两条查询中,COUNT 聚集函数都返回 4 ,是 INSERT 语句加载到 foo 中的总行数。因为 nc 列是 NLS 数据类型,所有的行都满足 WHERE 子句中的 nc = 'gbase' 条件,尽管在 nc 值中有字母大小写的变化。
在同一表上执行以下查询,
SELECT nc FROM foo GROUP BY nc;
输出可能是来自 INSERT 语句的任何字符串值(亦即 'GBASE' 、'gBASE' 、'gbase' 、'gbaSE' 或 'GBase'),这取决于服务器处理或扫描行的顺序。
在同一表上的下一查询,通过在投影子句中包含 DISTINCT 关键字从结果集排除了重复的行:
SELECT DISTINCT nc FROM foo;
此处返回一行,因为从 NLSCASE INSENSITIVE 角度来看,所有的行具有相同的值,尽管在字母大小写上有变化。正如先前的示例,从插入的行中检索到的第一行将由查询返回。
以下示例包含 DISTINCT 关键字,将其作为 COUNT 聚集函数其中的一个参数:
SELECT COUNT(DISTINCT nc) FROM foo;
此处还是返回计数 1,因为在此不区分大小写的数据库中,foo 表中所有的行都评估为重复行。
NLSCASE INSENSITIVE 数据库的限制
以下限制应用于创建 NLSCASE INSENSITIVE 属性的数据库:
l 它们支持只与拥有 NLSCASE INSENSITIVE 属性的数据库的分布跨数据库和跨服务器查询。
l 区分大小写的数据库无法连接到 NLSCASE INSENSITIVE 数据库。若要尝试此操作,则会产生以下错误:
-26801 Cannot reference an external database that is not case sensitive.
l NLSCASE INSENSITIVE 数据库无法连接到区分大小写的数据库。若要尝试此操作,则会产生以下错误:
-26802 Cannot reference an external database that is case sensitive.
唯一的例外是,NLSCASE 设置不会阻止同一 GBase 8s 数据库服务器实例到区分大小写系统数据库(例如 sysmaster 、sysadmin 、sysutils 、sysusers 和 syscdr)的连接。存取系统数据库操作的结果依赖于其它数据库中的 NLSCASE 设置。
l onload 和 onunload 实用程序不支持具有 NLSCASE INSENSITIVE 属性的数据库。
使用 CREATE DISTINCT TYPE 语句创建新的 distinct 数据类型。
该语句是 SQL ANSI/ISO 标准的扩展。
语法
用法
Distinct 类型是基于内置数据类型或现有不透明数据类型,指定的 ROW 数据类型或者其它 Distinct 数据类型的数据类型。Distinct 数据类型是强归类的。虽然 Distinct 类型与其源类型对数据有相同的物理表示法,但两种类型的值在没有从一种类型到另一种类型的显式强制转型的情况下无法进行比较。
要创建 Distinct 数据类型,您必须拥有数据库上的 Resource 权限。任何拥有 Resource 权限的用户均可从内置数据类型之一创建 Distinct 类型,而该用户是用户 gbasedbt 所拥有的。
重要: 不能在 SERIAL 、BIGSERIAL 或 SERIAL8 数据类型上创建 Distinct 类型。
要从不透明类型、指定的 ROW 类型或另一 Distinct 类型创建 Distinct 类型,您必须是该数据类型的所有者或在该数据类型上拥有 Usage 权限。
缺省情况下,一旦定义了 Distinct 类型,之一该 Distinct 类型的所有者和 DBA 可以使用它。然而,Distinct 类型的所有者可向其他用户授权对该 Distinct 类型的 Usage 权限。
Distinct 类型与其源类型有相同的存储结构。以下语句创建了基于内置 DATE 数据类型的 Distinct 类型 birthday:
CREATE DISTINCT TYPE birthday AS DATE;
虽然 GBase 8s 使用对 Distinct 类型以及它的源类型使用相同的存储格式,但 Distinct 类型与其源类型不能在一个操作中进行比较,除非一个类型显式强制转型到另一个类型。
如果您包含了 IF NOT EXISTS 关键字,当指定名称的 Distinct 数据类型已经在当前数据库中注册过时,则数据库服务器不采取任何操作(而不是向应用程序发送异常)。
要创建 Distinct 类型,您必须拥有该数据库上的 Resource 权限。当创建 Distinct 类型时,只有您,即所有者对此类型拥有 Usage 权限。使用 GRANT 或 REVOKE 语句向其它数据库用户授权或调用 Usage 权限。
要找出特定类型上存在哪些特权,请在 sysxtdtypes 系统目录表中检查所有者名称,并在 sysxtdtypeauth 系统目录表中检查可能已经授予的其它数据类型特权。有关系统目录表的更多信息,请参阅 《GBase 8s SQL 指南:参考》 。
DB-Access 实用程序也可显示对 Distinct 类型的特权。
当您创建 Distinct 类型时, GBase 8s 自动定义两种显式强制转型:
l 从 Distinct 类型到其源类型的强制转型
l 从源类型到 Distinct 类型的强制转型
因为这两个数据类型具有相同的表示法(相同的长度和对齐方式),所以实现这些强制转型不需要支持函数。
您可在 Distinct 类型与其源类型之间创建隐式强制转型。要创建隐式强制转型,请使用 Table Options 子句来指定外部数据的格式。然而,您必须首先删除 Distinct 类型与其源类型之间的缺省显式强制转型。
在源类型上定义的所有支持函数的强制转型可用于 Distinct 类型。然而,对 Distinct 类型定义的强制转型和支持函数对源类型不可用。请使用 Table Options 子句指定外部数据的格式。
当将 Distinct 类型与其源类型进行比较或操纵它们的数据时,在以下情况中您必须显式地将一种类型强制转型为其它类型:
l 使用其它类型的值插入或更改一种类型的列
l 使用关系运算符来加、减、乘、除、比较或以其它方式操纵两个值,一个源类型的值和一个 Distinct 类型的值
例如,假设您创建了 Distinct 类型 dist_type ,它基于 NUMERIC 数据类型。然后您创建了带有两列的表,一个属于 dist_type 类型,一个属于 NUMERIC 类型。
CREATE DISTINCT TYPE dist_type AS NUMERIC;
CREATE TABLE t(col1 dist_type, col2 NUMERIC);
要直接将 Distinct 类型与其源类型进行比较或者将源类型的值分配到 Distinct 类型的列上,您必须将一种类型强制转型到其它类型,如以下示例所示:
INSERT INTO tab (col1) VALUES (3.5::dist_type);
SELECT col1, col2
FROM t WHERE (col1::NUMERIC) > col2;
SELECT col1, col2, (col1 + col2::dist_type) sum_col
FROM tab;
有关在本地数据库外的表内存取 DISTINCT 数据类型的查询和其它分布 DML 操作的信息,请参阅 分布式操作中的 DISTINCT 类型 。